<?php
/**
 * Name: cartnew.php
 * Desc: This class is designed to provide a basic, extendable framework for an eCommerce backend.
 *
 * Version: 1.5
 *
 * Date:    (Revised) May 30, 2007 and many more
 * Author:  Christopher J. Burdick
 **/

require_once('db.class.php');

if (!isset($_SESSION)) {
	if (!isset($SITEROOT)) $SITEROOT = '../../../';
	require_once($SITEROOT . 'manager/includes/config.inc.php');
	startCMSSession();
}

class Kiwee {
	public $config = array();
	public $db;
	
	function __construct(){
		// Connect to the database		
		$this->db = new db();

		// Just in case we change the name again =)
		// Stores the prefix of the ecommerce tables
		$this->loadConfig();
	}
	
/**
 * loadConfig will load the config options from the database
 **/
	private function loadConfig(){
	
		//Updated by Bright @ 20080722	
		//Cause there is a bug that pfx is not changing after installation, So I just manually change it to what we need.
		//$this->config['pfx'] = 'modx_';
		//$this->config['fpx'] = 'modx_kiwee_';
		//$this->config['ecp'] = 'kiwee_';
		$this->config['pfx'] = 'modx_';
		$this->config['fpx'] = 'modx_kiwee_';
		$this->config['ecp'] = 'kiwee_';
		// Grab Config Data
		$result = $this->db->sel($this->config['fpx'], 'config_values', 'optname, optval');
		$row = $result;
		// Load Config Array
		for ($i=0; $i < sizeof($row); $i++){
			$this->config[$row[$i]['optname']] = $row[$i]['optval'];
		}
		// Added two params that I don't want people to have direct access to as they are only used for changing
		// the table prefix for the ecommerce tables.  It is mostly used for testing with older versions of 
		// Kiwee.
	}
	
/**
 * unloadConfig will unload the config options from memory
 **/
	
	private function unloadConfig(){
		$this->config=array();	
	}
	
/**
 * reloadConfig will just call out to unloadConfig followed by loadConfig to recreate the
 * config database in case this has to be done on the fly for a particular method...perhaps
 * when new config options are created dynamically or if we modify existing config options.
 **/
	
	public function reloadConfig(){
		$this->unloadConfig();
		$this->loadConfig();
	}
	
/**
 * This function is designed to create a shopping cart.  Without any items, the shopping cart is simply
 * an entry in kiwee_cart_header
 * 
 * @param sessionid		- The Session ID of the user whose cart we are creating
 * 
 * @return the id and session_id that were added to the database
 **/
    public function createCart($sessionid){
		$result = $this->db->sel($this->config['fpx'], 'cart_header', 'id, datemodified, subtotal, itemsincart, session_id', 'session_id="' . $sessionid . '"');
		if (sizeof($result) > 0){
	        $headerinfo = $result[0];
		} else {
			$headerinfo = "";
		}
		
        $dat = date("D M j G:i:s T Y");

        if ($sessionid != $headerinfo['session_id']){
            $this->db->ins($this->config['fpx'], 'cart_header',  'session_id, dateadded', '"' . $sessionid . '","' . $dat . '"');
            $result=$this->db->sel($this->config['fpx'], 'cart_header', 'id, session_id', 'session_id="' . $sessionid . '"');
            $headerinfo = $result[0];
        }
        return $headerinfo;
    }
	
/**
 * This function will take in a contentid and return the mySQL id of an item.
 *
 * @param   contentid       =   The MODx content id (mysql id of the page which the item resides on)
 *
 * @return  The MySQL id of the item
 **/
    public function getItemId($contentid){
        $result = $this->db->sel($this->config['fpx'], 'items', 'id', 'content_id=' . $contentid);

        return $result[0]['id'];
    }

	
/**
 * This function is designed to obtain or create a cart header, and then add a new entry to the detail
 * table for the item that the user added to their cart.
 * 
 * @param	id			=	mySQL ID of the item 
 * @param	sessionid	=	Session ID of the user
 * @param 	opts		= 	Associative array of the options chosen when the item was added
 * @param	qty			=	Item Quantity
 * 
 * @return	A string which displays the number of items in the cart with a link to view the cart.  																																																																																																																									   *$HE																																																																																																																			   * NOTE: This may be a config variable in the future
 **/
																																																																																																																										 
	public function addToCart($id, $sessionid, $opts, $qty){
		$id = $this->getItemId($id);
        $qty = $qty > 0 ? $qty : 1;
        $hdrinfo = $this->createCart($sessionid);

        // Check to make sure cart was created
		
        $dat = date("D M j G:i:s T Y");

        $itincart = intval($hdrinfo['itemsincart']);

		
        // Get options pricing
        $optionsreturn = $this->getOptionsPricing($opts, $id, $qty);
		


        $result = $this->db->sel($this->config['fpx'], 'items', 'amount', 'id=' . $id);
        $item = $result[0];

        if (isset($id)){
            $result = $this->db->sel($this->config['fpx'], 'cart_detail', 'id,quantity,options,optionsprice,totalprice','header_id=' . $hdrinfo['id'] . ' AND item_id=' . $id);

            $flag=false;
            $num = sizeof($result);
            for ($k=0; $k < $num; $k++){
                $res = $result[$k];
                if ($res['options']==$optionsreturn['optstring']){
                    $itincart = $itincart + $qty;
                    $quantity = $res['quantity'] + $qty;
                    $prc = floatval($item['amount']);
											
                    $newprc=floatval($hdrinfo['subtotal']) + ($prc * $qty) + floatval($optionsreturn['price']);
				
                    $optsprice=floatval($res['optionsprice']) + floatval($optionsreturn['price']);
                    $totalprice = floatval($res['totalprice']) + (floatval($prc) * $qty) + floatval($optionsreturn['price']);
                    $this->db->upd($this->config['fpx'], 'cart_detail', 'quantity=' . $quantity . ', optionsprice=' . $optsprice . ', totalprice=' . $totalprice, 'header_id=' . $hdrinfo['id'] . ' AND id=' . $res['id']);
                    $this->db->upd($this->config['fpx'], 'cart_header', 'datemodified="' . $dat . '", itemsincart=' . $itincart . ', subtotal=' . $newprc, 'id=' . $hdrinfo['id']);
					$flag=true;
                }
           }
										
            if ($flag==false){
				// In case there was already one in the cart but the options were NOT equal...add new record
                $itincart= $itincart + $qty;
                $result = $this->db->sel($this->config['fpx'], 'items', 'amount', 'id=' . $id);
                $item = $result[0];
                $prc = floatval($item['amount']);
                $totalprice = (floatval($prc) * $qty) + floatval($optionsreturn['price']);
                $newprc = floatval($hdrinfo['subtotal']) + ($prc * $qty) + floatval($optionsreturn['price']);
                $this->db->upd($this->config['fpx'], 'cart_header', 'datemodified="' . $dat . '", itemsincart=' . $itincart . ', subtotal=' . $newprc, 'id=' . $hdrinfo['id']);
				$this->db->ins($this->config['fpx'], 'cart_detail', 'header_id, item_id, quantity, date, options, optionsprice, totalprice', $hdrinfo['id'] . ', ' . $id . ', ' . $qty . ', "' . $dat . '", "' . addslashes($optionsreturn['optstring']) . '", ' . floatval($optionsreturn['price']) . ', ' . $totalprice);
                $result = $this->db->sel($this->config['fpx'], 'cart_detail', 'id', 'header_id=' . $hdrinfo['id'] . ' AND item_id=' . $id);
                $detail_id = $result[0];
            }
         }
				
        $quant = $this->getItemCount($sessionid);
        $cartNotifier= isset($quant) ? 'You have ' . $quant : 'You have 0 items in your shopping Cart!';
				
        if ($quant > 1) {
	        $cartNotifier .= ' items in your shopping cart totaling: $' . floatval($newprc);
        }  else if ($quant == 1) {
            $cartNotifier .= ' item in your shopping cart totaling: $' . floatval($newprc);
        }
				
        $cartNotifier .= '<br />';
        $cartNotifier .= '<a href="index.php?id=' . $this->config['cart_additempage'] . '&sessionid=' . $sessionid . '">View Cart</a>';
				
        return $cartNotifier;				
	}
		
/**
 * This function is designed to take an encoded string of the options that a user passes when their item is added to the cart and figure the item's price
 * appropriately.
 * 
 * @param	opts	=	Encoded string of the options selected on the website
 * @param	id		=	ID of the item we are adding (MySQL ID)
 * @param	qty		=	Qty, so we can figure out the total options pricing (not just for qty=1)\
 * 
 * @return 	An array with the options selected and their pricing
 **/
	private function getOptionsPricing($opts, $id, $qty){
        // Init Vars
        $ret['price'] = 0;
        $ret['optstring'] = '';
		
		//find (~(AND)~)  and convertet back to &
		$opts =str_replace('\"','&quot;',$opts);
		$opts =str_replace("\'",'&#39;',$opts);
		$opts =str_replace("\\",'&#92;',$opts);		
		
		
        // Break opts passed from site into an array
        $splitopts = explode("||||", $opts);
		
		
		
        for ($i=0; $i < sizeof($splitopts); $i++){
					
			//Split name of option from value
      		$splitnameval = explode('::::', $splitopts[$i]);
		
        	// Store Option Name
        	$optsfromsite[$i][0] = $splitnameval[0];
		
			$splitnameval2 = explode(',,,,', $splitnameval[1]);
			
			// Store value(s) chosen by customer
        	$optsfromsite[$i][1] = $splitnameval2[0];
						
			//added by Bright @20080801 
			//store the priceoffset of that option
			$optsfromsite[$i][2] = $splitnameval2[1];

		
        	// Get Option Render just so we know what to do to get all values and what to return to the user.
        	$optinfo = $this->getOptionByName($optsfromsite[$i][0]);
			
            /** 
		  	 * It is important to check, as we don't want to obtain options from a TEXT
			* or TEXT Area and we only need to loop through multiple options for
			* a CHECK or SELECT
			**/
			 
			 
            if ($optinfo['renderas']=='CHECK' || $optinfo['renderas']=='MULTI'){
	 	      	// checkbox and multi selects send info as id;;;;id;;;;id;;;; etc...
               	$optsvalsplit=explode(';;;;', $optsfromsite[$i][1]);
               	$flag = false;
               	$first = true;
               	for ($j=0; $j < sizeof($optsvalsplit); $j++){
	            	//Just in case they choose no options
                   	if ($optsvalsplit[$j]!=""){
	                	$optproperties = $this->getListOptionProperties($optsvalsplit[$j]);
                       	$ret['price'] = $ret['price'] + (floatval($optproperties['offset']) * $qty);
                       	if ($first==true){
	                    	$optsvalname=$this->getListOptionProperties($optsvalsplit[$j]);
                           	$ret['optstring'] .= $optsfromsite[$i][0] . ': ' . $optsvalname['name'];
                           	$first=false;
                       	} else {
 	                    	$optsvalname=$this->getListOptionProperties($optsvalsplit[$j]);
                          	$ret['optstring'] .= ', ' . $optsvalname['name'];
                       	}
                        $flag=true;
                    } else {
 	                   if ($flag==false){
	                       $ret['optstring'] .= $optsfromsite[$i][0] . ': None';
                       }
                    }
                }
                $ret['optstring'] .= '<br />';
            } else if ($optinfo['renderas']=='SELECT' || $optinfo['renderas']=='DROP' || $optinfo['renderas']=='RADIO'){

	             $optproperties = $this->getListOptionProperties($optsfromsite[$i][1]);
				 //Edited by Bright @ 20080801
                 //$ret['price'] = $ret['price'] + (floatval($optproperties['offset']) * $qty);
				 $ret['price'] = $ret['price']+$optsfromsite[$i][2] * $qty;
				 $ret['optstring'] .= $optsfromsite[$i][0] . ": " . $optproperties['name'] . '<br />';
			} else if ($optinfo['renderas']=='SELECTANDEDIT'){
			//edited by Bright @20080730 
			//currently the value of $optsfromsite[$i][1] is "12|||:::adfaso;diujaihsdfaiousdvyhlakjhelwkjhf" split again
				 $splitselectandedit = explode('|||:::', $optsfromsite[$i][2]);
				 $optsfromsite[$i][2] = $splitselectandedit[0];
				 $optproperties = $this->getListOptionProperties($optsfromsite[1]);
				 //Edited by Bright @ 20080801
                 //$ret['price'] = $ret['price'] + (floatval($optproperties['offset']) * $qty);
				 $ret['price'] = $ret['price']+$optsfromsite[$i][2] * $qty;
				 $ret['optstring'] .= $optsfromsite[$i][0] . ": " . $optproperties['name'] . '<br />Text: '.$splitselectandedit[1].'<br/>';
			} else if ($optinfo['renderas']=='TEXT' || $optinfo['renderas']=='TEXTAREA'){
				 $ret['optstring'] .= $optsfromsite[$i][0] . ": " . $optsfromsite[$i][1] . '<br />';
			} 
        }		

		return $ret;
	}
		
/**
 * This function is designed to handle loading the data for a particular item from the audit table.
 * 
 * @param id	=	itemid
 **/
	public function getItemProperties($id){
        $result = $this->db->sel($this->config['fpx'], 'items_audit', 'id, content_id, sku, name, fullname, description, amount, oversized, hazmat, disabled, shoppingenabled, quoteenabled, status', 'id=' . $id);
        $row = $result[0];

        $itemprops['id'] = $row['id'];
        $itemprops['content_id'] = $row['content_id'];
        $itemprops['sku'] = $row['sku'];
        $itemprops['name'] = $row['name'];
        $itemprops['fullname'] = $row['fullname'];
        $itemprops['amount'] = $row['amount'];
        $itemprops['oversized'] = $row['oversized'];
        $itemprops['hazmat'] = $row['hazmat'];
        $itemprops['disabled'] = $row['disabled']==0 ? 'ENABLED' : 'DISABLED';;
        $itemprops['shoppingenabled'] = $row['shoppingenabled']==0 ? 'DISABLED' : 'ENABLED';
        $itemprops['quoteenabled'] = $row['quoteenabled']==0 ? 'DISABLED' : 'ENABLED';
        $itemprops['status'] = $row['status'];		

        $result = $this->db->sel($this->config['pfx'], 'site_content', 'template, content, longtitle, description', 'id="' . $itemprops['content_id'] . '"');
        $row = $result[0];
	
        $itemprops['pagetemplate'] = $row['template'];
        $itemprops['contentarea'] =  $row['content'];
        $itemprops['longtitle'] = $row['longtitle'];
        $itemprops['description'] = $row['description'];		
		
		return $itemprops;
	}
		
/**
 * This function is designed to handle updating an items options in items_options
 *
 * @param		itemid		=	The ID (MySQL) of the item to update
 * @param		chosenopts	=	The ID's of the chosen options for an item
 **/
	public function updateItemOptions($itemid, $chosenopts){
		// Delete all options first that are already associated with the item
		$this->db->del($this->config['fpx'], 'items_options', 'item_id=' . $itemid);
		
		// Read new options
		for ($i=0; $i < sizeof($chosenopts); $i++){
			$this->db->ins($this->config['fpx'], 'items_options', 'options_id, item_id', $chosenopts[$i] . ', ' . $itemid);	
		}
	}
		
/**
 * This function is designed to handle item page updates.  If the ID is 0, it is new...if the ID is > 0 it means the page is being updated
 *
 * @param   itemid              = MySQL ID of the item to be edited  (NOTE:  if 0, it indicates that the item is new)
 * @param   itemname            = Name of the Item
 * @param   shortdescription    = Longer description of the item (but still short)
 * @param   contentarea         = The main templated content area
 * @param   price               = Price of the Item
 * @param   hazmat              = Hazmat fee for shipping
 * @param   oversized           = Oversized shipping fee
 * @param   status              = Audit Status =>  Whether the item is updated, new, etc.  This is mostly for use by Blackbird...our open source ESB offering
 *                                for QuickBooks integration
 * @param   active              = Tells whether the item is active or inactive
 * @param   enablequote         = Is the quote basket enabled?
 * @param   template            = Overall page template
 * @param   enableshop          = Is the Shopping Cart enabled for this item?
 **/
	public function updatePage($itemid, $sku, $itemname, $shortdescription, $contentarea, $price, $hazmat, $oversized, $status, $active, $enablequote, $template, $enableshop){
		// Convert Booleans to binary
		if ($enableshop=='true'){$enableshop = 1;}else{$enableshop = 0;}
		if ($enablequote=='true'){$enablequote = 1;}else{$enablequote = 0;}
		if ($active=='true'){$active= 0;}else{$active=1;}
		if ($itemid == 0){ // New Item
			$itemid = $this->writeItemToDB($itemid, $itemname, $sku, $shortdescription, $price, $hazmat, $oversized, $enableshop, $enablequote, $active, 'NEW');
		
			//Config - Probably shouldn't touch too much here...perhaps changing a template
			$parent= 4008;
			$richtext= 1;
			$searchable= 1;
			$cacheable= 0;
			$published= 1;	
			$contentid = $this->addContainer($itemid, $sku, $contentarea, $itemname, $shortdescription, $shortdescription, $published, $parent, $richtext, $template, $searchable, $cacheable, $itemname, 'NEW');
        	// add container id to the item in the database (for easy update and retrieval of the correct site content
        	$this->db->upd($this->config['fpx'], 'items', 'content_id=' . $contentid, 'id=' . $itemid);
        	$this->db->upd($this->config['fpx'], 'items_audit', 'content_id=' . $contentid, 'items_id=' . $itemid);
        }else { // Updated Item
			$itemid = $this->writeItemToDB($itemid, $itemname, $sku, $shortdescription, $price, $hazmat, $oversized, $enableshop, $enablequote, $active, 'UPDATED');
            $result  = $this->db->sel($this->config['fpx'], 'items_audit', 'content_id' , 'items_id=' . $itemid);
            $row = $result[0];
            $contentid = $row['content_id'];
            //Update Container Page
			$this->updateContainer($contentid, $itemid, $sku, $contentarea, $itemname, $shortdescription, $shortdescription, $published, $parent, $richtext, $template, $searchable, $cacheable, $itemname, 'NEW');
		}
	}
		
/**
 * This function is used for updating an item already in a cart.  If the quantity is set to zero it will delete the item,
 * otherwise it will update the item record from the cart.
 * 
 * @param      sku             =   SKU of the item
 * @param      sessionid       =   Session ID of the user
 * @param      qty             =   Item Quantity
 * @param      opts            =   Options which were chosen with the item
 * @param      detailid        =   The detailid is included to make sure we delete or update the correct item from the user's cart
 **/
	public function updateItem($sessionid, $sku, $qty, $opts, $detailid){
		$result = $this->db->sel($this->config['fpx'], 'cart_header', 'id', 'session_id="' . $sessionid . '"');
		$header_id = $result[0];
		
		$result = $this->db->sel($this->config['fpx'], 'items', 'id', 'sku="' . $sku . '"');
		$item_id = $result[0];
		
		$options = encodeOptions($opts, $item_id['id']);
		
		$dat = date("D M j G:i:s T Y");
		
		if ($qty==0){
			$this->db->del($this->config['fpx'], 'cart_detail', 'header_id="' . $header_id['id'] . '" AND item_id="' . $item_id['id'] . '" AND id=' . $detailid);
		} else {
			$this->db->upd($this->config['fpx'], 'cart_detail', 'quantity=' . $qty . ', date="' . $dat. '", options="' . $opts['options'] . '", optionsprice=' . floatval($opts['price']), 'id=' . $detailid . ' AND item_id=' . $item_id);	
		}
	}
	
/**
 *  This function is used if you want to delete an item without passing me a quantity of zero.  If you're using this you might be considered lazy.
 *  Just pass me your session id and item number and I guess I'll take care of it.
 *
 *  @param      sessionid       =   Session ID of the user
 *  @param      detailid        =   This is the id of the detail line to delete
 **/
    function deleteItem($sessionid, $itemid){
        $result = $this->db->sel($this->config['fpx'], 'cart_header', 'id, datemodified, itemsincart, subtotal', 'session_id="' . $sessionid . '"');
        $headrec = $result[0];

        $result = $this->db->sel($this->config['fpx'], 'cart_detail', 'quantity, totalprice', 'header_id=' . $headrec['id'] . ' AND id=' . $itemid);
        $record = $result[0];

        $subtotal = floatval($headrec['subtotal']) - floatval($record['totalprice']);
        $itemsincart = floatval($headrec['itemsincart']) - floatval($record['quantity']);
		if ($itemsincart < 0){
			$itemsincart=0;	
		}
        $datemodified = date("D M j G:i:s T Y");
	
        $this->db->del($this->config['fpx'], 'cart_detail', 'header_id=' . $headrec['id'] . ' AND id=' . $itemid);
        $this->db->upd($this->config['fpx'], 'cart_header', 'subtotal=' . $subtotal . ', itemsincart=' . $itemsincart . ', datemodified="' . $datemodified . '"', 'id=' . $headrec['id']);
    }
	
		
/**
 * This function is used for encoding the options string.  This will return an array containing the options string and the optionsvalue
 * 
 * @param		opts	=	This is an of the names of the options which were selected for an item.
 * @param		item_id	=	This is the ID (MySQL) of the item.
 **/
	public function encodeOptions($opts, $item_id){
		$price = 0;
		
		foreach($opts as $var => $value){
			$option = $this->getOption($item_id, $var);
			$listitem = $this->getListOption($option['listid']);
			$price = $price + (floatval($listitem['priceoffset']));
			$options = $options + $listitem['name'] + ':' + $value + ';';
		}
		
		$arr['options'] = $options;
		$arr['price'] = $price;
		return $arr;
	}
		
/**
 * This function is designed as a gateway to process various types of checkouts.
 * It's only purpose is to redirect to the appropriate handler for the checkout
 * method chosen during the checkout process.
 **/
	public function processCheckout($sessionid, $paymethod, $cardtype, $nameoncard, $cardnum, $routenum, $cvvcode, $expmo, $expyr){
        switch ($paymethod){
	        // Credit Line offered by Merchant
            case "CREDIT":
//                return "MADE IT CREDIT";
            break;
            // Mail a Check
            case "CHECK":
//                return "MADE IT CHECK";
            break;
            // Process a credit card with authorize.NET
            case "CREDITCARD":
                $headerid= $this->convertToOrder($sessionid);
			
				$cc['cardtype'] = $cardtype;
			    $cc['nameoncard'] = $nameoncard;
			    $cc['cardnum'] = $cardnum;
			    $cc['cvvcode'] = $cvvcode;
			    $cc['expmo'] = $expmo;
			    $cc['expyr'] = $expyr;
                $response= $this->processCC($cc);
            break;
            // Process an eCheck with authorize.NET (not yet implemented)
            case "ECHECK":
//                return "MADE IT ECHECK";
            break;
            // Add order from a google Checkout (Google takes care of the rest)
            case "GOOGLE":
//                return "MADE IT GOOGLE";
            break;
            // Add order from a paypal Checkout (Paypal takes care of the rest)
            case "PAYPAL":
//                return "MADE IT PAYPAL";
            break;
        }		
	}
		
/**
 * This function converts a cart into an order and sets the appropriate customer id to the order
 * 
 * @param		sessionid	=	Session ID of the user attempting to check out
 * 
 * @return The Header ID (MySQL) of the order that was inserted
 **/
	private function convertToOrder($sessionid){
        // This is the entire header record from the cart in $hid[0] -> $hid[23]
		$flds = 'id, itemsincart, subtotal, fname, lname, addr1, addr2, city, state, zip, phone_1, phone_2, ext_1, ext_2, fax, company, shipfname, shiplname, shipaddr1, shipaddr2, shipcity, shipstate, shipzip, shipphone, shipext, shipcompany';
		$result = $this->db->sel($this->config['fpx'], 'cart_header', $flds, 'session_id="' . $sessionid . '"');
        $hedr=$result[0];
		
        // $cust['internalKey'] is the internalKey of the modx user with the sessionid that was passed in, it should be linked to the customer's orders so
        // that their orders will properly show up in the customer account viewer.
        $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'internalKey', 'sessionid="' . $sessionid . '"');
        $cust=$result[0];
		
        // Get Shipping and Handling for order
        $tshp = $this->getShip($sessionid);
        $thnd = $this->getHandle($sessionid);
        $rate = floatval($this->config['tax_percentage']);
        $ttax = $this->getTax($sessionid, $rate);
        $totl = $this->gettotal($sessionid, $rate);
		
		//added by Bright @ 20080807
		//Get the currency of the order include currency ISO and Currency Rate
		$curriso = $_SESSION['CURRENCY'];
		$currate = $this->getCurRate($curriso);
		//$cursym = $this->getCurSym($curriso); //no need in this stage
		
		
		
		
		// Generate Date for created entry
        $dat = date("D M j G:i:s T Y");
	    // Copy Cart to an Order
		$tbl = 'order_header';
		$flds = 'cust_id, totshipping, tothandling, tax, total, subtotal, currency, currrate, status, orderitems, created, fname, lname, addr1, addr2, city, state, zip, phone_1, phone_2, ext_1, ext_2, fax, company, shipfname, shiplname, shipaddr1, shipaddr2, shipcity, shipstate, shipzip, shipphone, shipext, shipcompany';
		
		// Headerline information
		if ($cust['internalKey'] == ''){
			$c = 0;	
		} else {
			$c = $cust['internalKey'];	
		}
		$headerline = $c . ', ' . $tshp . ', ' . $thnd . ', ' . $ttax . ', ' . $totl . ', "'. $curriso .'",'. $currate. ', ' . $hedr['subtotal'] . ',"NEW" , ' . $hedr['itemsincart'] . ', "' . $dat . '", ';
		
		// Billing Info
		$billingline = '"' . $hedr['fname'] . '", "' . $hedr['lname'] . '", "' . $hedr['addr1'] . '", "' . $hedr['addr2'] . '", "' . $hedr['city'] . '", "' . $hedr['state'] . '", "' . $hedr['zip'] . '", "' . $hedr['phone_1'] . '", "' . $hedr['phone_2'] . '", "' . $hedr['ext_1'] . '", "' . $hedr['ext_2'] . '", "' . $hedr['fax'] . '", "' . $hedr['company'] . '", ';
		
		// Shipping Info
		$shippingline = '"' . $hedr['shipfname'] . '", "' . $hedr['shiplname'] . '", "' . $hedr['shipaddr1'] . '", "' . $hedr['shipaddr2'] . '", "' . $hedr['shipcity'] . '", "' . $hedr['shipstate'] . '", "' . $hedr['shipzip'] . '", "' . $hedr['shipphone'] . '", "' . $hedr['shipext'] . '", "' . $hedr['shipcompany'] . '"';

		// Add Header
		$this->db->ins($this->config['fpx'], 'order_header', $flds, $headerline . $billingline . $shippingline);
		
		// Get Header ID
		$result = $this->db->sel($this->config['fpx'], 'order_header', 'id', 'created="' . $dat . '" AND cust_id=' . $c);
		$headid = $result[0];
		
		// Get Items from the cart to copy into the order
		$result = $this->db->sel($this->config['fpx'], 'cart_detail', 'item_id, quantity, options, optionsprice, totalprice', 'header_id=' . $hedr['id']);
		$cartitems = $result;
		
		// Transfer Items from cart to the order
		for ($i=0; $i < sizeof($cartitems); $i++){
			$row = $result[$i];
			$this->db->ins($this->config['fpx'], 'order_detail', 'item_id, order_id, quantity, options, optionsprice, totalprice', $row['item_id'] . ', ' . $headid['id'] . ', ' . $row['quantity'] . ', "' . $row['options'] . '", ' . $row['optionsprice'] . ', ' . $row['totalprice']);
		}
		
		// Delete cart detail
		$this->db->del($this->config['fpx'], 'cart_detail' , 'header_id=' . $hedr['id']);
		
		// Delete cart header
		$this->db->del($this->config['fpx'], 'cart_header', 'id=' . $hedr['id']);
		
		// Return order header id
		return $headid['id'];
	}
		
/**
 * There are too many parameters to list (and most are obvious)
 *
 * The reason that I didn't just create my own login system is because I figure that most modx users
 * who have an existing website, most likely have existing users.  Thus I don't want to make them
 * switch to a new authentication mechanism.  The other nice thing is that the ModX module already
 * takes care of the login process fairly well, so I didn't see a need to rewrite it.  However, it
 * only takes in fields which would be associated with posting to a forum or blog...whereas ecommerce
 * often requires other fields to be stored for customer accounts (ie: an exact address rather than
 * just a country).  So my module piggy-backs on the existing one.  I first create the modx user
 * and then I create my kiwee_customers entry to store additional data. 
 *
 * @return The id of the user account I just created (if needed by the caller)
 **/
	public function createUserAccount($sessionid, $email, $fname, $lname, $addr1, $addr2, $city, $state, $zip, $country, $phone, $ext, $fax, $company, $username, $password){
        // Create fullname
        $fullname = $fname . ' ' . $lname;
        // Create User Account
		
		
		//Updated by Bright @ 20080722	
		//the following code seems to be wrong.
		// $this->db->ins($this->config['pfx'], 'web_users', 'username, password' . ', "' . $username . '", "' . $password . '"');
	    $this->db->ins($this->config['pfx'], 'web_users',     'username, password', '"' . $username . '", "' . $password . '"');
	
        $result = $this->db->sel($this->config['pfx'], 'web_users', 'id', 'username="' . $username . '" AND password="' . $password . '"');
        $row = $result[0];
        $id=$row['id'];
		
        $this->db->ins($this->config['pfx'], 'web_user_attributes', 'internalKey, fullname, email, zip, state, country', $id . ', "' . $fullname . '", "' . $email . '", "' . $zip . '", "' .$state . '", "' . $country . '"');
		
		$this->db->ins($this->config['fpx'], 'customers', 'fname, lname, addr1, addr2, city, state, zip, country, phone_1, ext_1, fax, companyname, custid', '"' . $fname . '", "' . $lname . '", "' . $addr1 . '", "' . $addr2 . '", "' . $city . '", "' . $state . '", "' . $zip . '", "' . $country . '", "' . $phone . '", "' . $ext . '", "' . $fax . '", "' . $company . '", ' . $id);
		
		return $id;
	}
		
/**
 * This function will process a credit card transaction through the appropriate gateway
 * 
 * @param 		cc	=	Array of credit card information
 **/
		
	private function processCC($cc){
		$live = isset($this->config['authorize_live']) ? $this->config['authorize_live'] : 'FALSE';
		if ($live=='FALSE'){
			$resp['approval']='APPROVED';
			$resp['gway'] = 'authorizeNET';
			$random='';
   	     	for ($i=0; $i < 12; $i++){
		        $random .= rand(0,9);
   	     	}
   	     	for ($i=0; $i < 6; $i++){
   	         	$random2 .= rand(0,9);
   	     	}
   	     	$resp['authcode'] = $random;
   	     	$resp['trxnid'] = $random2;		
		} else {
			$resp = $this->authorizeDotNetCheckout($cc);	
		}
		
		return $resp;
	}
		
/**
 * This function is designed to tell us how many items are in a particular users cart.
 * 
 * @param 	sessionid		=	The customer's session ID
 **/
	public function getItemCount($sessionid){
		$result = $this->db->sel($this->config['fpx'], 'cart_header', 'itemsincart', 'session_id="' . $sessionid . '"');
		$numitems = $result[0];
		
		return $numitems['itemsincart'];
	}
				
/**
 * This returns the fullname of the item stored in the database
 * 
 * @param	itemid	=	The MySQL id of the item in the database
 * 
 * @return full name of the item from the database
 **/
	public function getFullName($itemid){
		$result = $this->db->sel($this->config['fpx'], 'items', 'fullname', 'id=' . $itemid);
		$row = $result[0];
		
		return $row['fullname'];
	}
		
/**
 * This returns the description of the item from the database
 * 
 * @param 	itemid	=	The MySQL id of the item in the database
 * 
 * @return 	description of the item from the database
 **/
	public function getDescription($itemid){
		$result = $this->db->sel($this->config['fpx'], 'items', 'description', 'id=' . $itemid);
		$row = $result[0];
		
		return $row['description'];
	}
	
/**
 * This function returns the short name of the item from the database
 * 
 * @param 	itemid		= The MySQL id of the item in the database
 * 
 * @return 	name of the item from the database
 **/
		
	public function getName($itemid){
		$result = $this->db->sel($this->config['fpx'], 'items', 'name', 'id=' . $itemid);
		$row = $result[0];
		
		return $row['name'];
	}
		
/**
 * This function returns the price of the item from the database
 * 
 * @param	itemid		=	the MySQL id of the item in the database
 * 
 * @return 	numberformat value of the price from the database for the item
 **/
	public function getPrice($itemid){
		$result = $this->db->sel($this->config['fpx'], 'items', 'amount', 'id=' . $itemid);
		$row = $result[0];
		return /**Bright @ 20080722 number_format(Bright @ 20080722 **/$row['amount']/**Bright @ 20080722 , 2)Bright @ 20080722 **/;
	}
		
/**
 * This returns a customer's subtotal
 * 
 * @param	sessionid	=	Session ID of the customer
 * 
 * @return	the subtotal in numberformat with 2 decimal places
 **/
	public function getSubtotal($sessionid){
		$result = $this->db->sel($this->config['fpx'], 'cart_header', 'subtotal', 'session_id="' . $sessionid . '"');
		$row = $result[0];
		
		return /**Bright @ 20080722number_format(Bright @ 20080722 **/$row['subtotal'] /**Bright @ 20080722, 2)Bright @ 20080722 **/;
	}
		
/**
 * This returns a customer's grand total.
 * 
 * @param 	sessionid	=	Session ID of the customer
 * 
 * @return 	grand total of the customer's order
 **/
	public function getTotal($sessionid){
		//$result = $this->db->sel($this->config['fpx'], 'cart_header', 'subtotal', 'session_id="' . $sessionid . '"');
		//$row = $result[0];
		$subt = $this->getSubtotal($sessionid);//floatval($row['subtotal']);
		$tax = $this->getTax($sessionid);
		$ship = $this->getShip($sessionid);
		$handle = $this->getHandle($sessionid);
		
		return $subt + $tax + $ship + $handle;
	}
		
/**
 * This returns the shipping cost for the customer's cart
 * 
 * @param	sessionid	=	Session ID of the customer
 * 
 * @return 	shipping cost of the customer's order
 * 
 * TODO: Implement a shipping gateway
 **/
	public function getShip($sessionid){
		$shipcost = 5.00;
		return /**Bright @ 20080722number_format(Bright @ 20080722 **/$shipcost /**Bright @ 20080722, 2)Bright @ 20080722 **/;
	}
		
/**
 * This returns the handling cost of the customer's cart
 * 
 * @param 	sessionid	=	Session ID of the customer
 * 
 * @return	handling cost of the customer's order
 **/
	public function getHandle($sessionid){
		$subtotal = $this->getSubtotal($sessionid);
		$handling = 0;
		
		if ($subtotal <= $this->config['handling_threshold']){
			$handling = floatval($this->config['handling_amount']);
		}

		return /**Bright @ 20080722number_format(Bright @ 20080722 **/$handling /**Bright @ 20080722, 2)Bright @ 20080722 **/;
	}
		
/**
 * Returns the taxable and non-taxable subtotals on a customer's order
 * 
 * @param	sessionid	=	Session ID of the customer
 * 
 * @return	array	0-taxable, 1-nontaxable
 **/
	public function calcSubtotals($sessionid) {
		
	}
	
/**
 * This returns the tax on a customer's order
 * 
 * @param	sessionid	=	Session ID of the customer
 * 
 * @return	Taxes on the order
 **/
	public function getTax($sessionid){
		$subtotal = $this->getSubtotal($sessionid);
		$taxpercent = floatval($this->config['tax_percentage']);
		
		if ($this->config['tax_enabled']=='ENABLED'){
			$taxes = $subtotal * $taxpercent;
		} else {
			$taxes = 0;
		}

		return /**Bright @ 20080722number_format(Bright @ 20080722 **/$taxes /**Bright @ 20080722, 2)Bright @ 20080722 **/;
	}
	
/**
 * This method is designed to provide a checkout button.
 * 
 * @return	= 	The code to produce a checkout button for the shopping cart -> payment information
 **/
	public function closeFormCheckout(){
		if ($this->config['cart_forcelogin'] == 'ENABLED'){
	        $button =  "<input class=\"itema_checkoutbutton\" type=\"submit\" value=\"Proceed to Checkout\" name=\"proceedtocheck\" onClick=\"checklogin();\" alt=\"Proceed to Login / Address \">";
		} else {
	        $button =  "<input class=\"itema_checkoutbutton\" type=\"submit\" value=\"Proceed to Checkout\" name=\"proceedtocheck\" onClick=\"gotoLogin();\" alt=\"Proceed to Login / Address \">";
		}
        return $button;
    }

/**
 * This method will provide the opening lines for a basic item form
 * 
 * @param 	name	=	Name of the form
 * @param 	itemid	=	mySQL id of the item who's form we are rendering
 * @param	action	=	The page to call when the form is sent
 * 
 * @return the code to open up a form
 **/
	public function openFormPHP($name, $itemid, $action){
        $open  = '<form name="' . $name . '" id="' . $name . '" method="POST" action="' . $act . '">' . "\n";
        return $open;		
	}
		
/**
 * This will create a basic form close with a submit button
 * 
 * @return	This will create an add to cart button that uses a PHP POST to submit
 **/
	public function closeFormPHP(){
		if ($this->config['cart_enabled'] == 'ENABLED'){
			$button  = '<input type="image" src="http://images.paypal.com/en_US/i/btn/x-click-but22.gif" border="0" name="submit" width="87" height="23" alt="Add to Cart!">';
			$button .= "\n</form>";
		
			return $button;
		} else {
			echo '<p>Contact Us for more information</p>';
			return "\n</form>";	
		}
	}
		
/**
 * This will create an open form chunk of HTML (for javascript add to cart systems)
 * 
 * @return	this will return the code to open a javascript form for adding items to a cart
 **/
	public function openFormJS(){
		$form  = '<form id="' . $id . '" method="POST" action="javascript: get(document.getElementById("' . $id . '"))" />';
		
		return $form;
	}
		
/**
 * This will create a button to add the item to the cart using AJAX via an XMLHttpRequest
 * 
 * @return	this will return a button that performs a javascript add to cart procedure instead of a postback page
 **/
	public function closeFormJS(){
		if ($this->config['cart_enabled'] == 'ENABLED'){
	        $button .= '<input type="hidden" id="item_id" name="item_id" value="[*id*]" />' . "\n";
		    $button .= '<input type="hidden" id="sessionid" name="sessionid" value="' . session_id() . '">' . "\n";
			$button .= '<input type="image" src="http://images.paypal.com/en_US/i/btn/x-click-but22.gif" border="0" name="submit"          onMouseOver="checkselection();" onclick="additemtocart();" width="87" height="23" alt="Add to Cart!">' . "\n";
        	$button .= '</form>';

        	return $button;
		} else {
			echo '<p>Contact Us for more information</p>';	
			echo '</form>';
		}
	}
		
/**
 * This will create a form button for returning to the catalog page you came from after adding an item to your cart
 * 
 * @return	The code to produce the button mentioned above
 **/
	public function closeFormReturnButton(){
		$button = '<input class="itema_checkoutbutton" type="submit" value="Continue Shopping" name="returntoshop" alt="Return to Shopping">';
		
		return $button;
	}
		
/**
 * This will create a form button which will bring the user to a form where they enter or check their stored billing / shipping addresses
 * 
 * @return	The code to produce a button to continue in the checkout process
 **/
	public function closeFormVerifyCheckout(){
		$button = '<input class="itema_checkoutbutton" type="submit" value="Verify" name="proceedtocheck" onClick="checkshipandbill();" alt="Verify for Checkout">';
		
		return $button;
	}
		
/**
 * This will create a form button which will validate the shipping / billing information and then continue to the next step in the process via javascript
 * 
 * @return	The code to produce a button which verifies the user-entered billing / shipping information
 **/
	public function closeFormSignupForm(){
		$button = '<input class="itema_checkoutbutton" type="submit" value="Signup" name="signupbutton" onMouseOver="checkusername();checkemail();" onClick="checksignup();" alt="Signup">';
		
		return $button;
	}
		
/**
 * This will create a form button which will process the final checkout screen
 * 
 * @return	The code to produce a button which processes the final checkout screen
 **/
	public function closeFormProcessCheckout(){
		$button = '<input class="itema_checkoutbutton" type="submit" value="Process Checkout" name="processcheckout" alt="Process Checkout">';
		
		return $button;
	}
	
/**
 * This will update a page in the ModX content page database (site_content)
 * 
 * @param		contentid	  =   ID of the content page being updated
 * @param		itemid		  =	  Don't leave home without it
 * @param		sku			  =	  Also a must have 
 * @param       pagetitle     =   Title of the page
 * @param       longtitle     =   Long title of the page
 * @param       description   =   Description of the page
 * @param       published     =   Boolean 1 Published / 0 Not
 * @param       parent        =   Integer FK relationship to parent document 49 for us
 * @param       richtext      =   Boolean 1 RT Editor / 0 Plain
 * @param       template      =   Integer FK relationship to template 7 for product template
 * @param       searchable    =   Boolean 1 Searchable / 0 Not
 * @param       cacheable     =   Boolean 1 Cacheable / 0 Not
 * @param       menutitle     =   Title to show in the menu 
 * @param		trxntype	  =	  The trxntype (UPDATED OR NEW)
 * 
 * @param	The MySQL ID of the content page that was just added to the database
 **/
	private function updateContainer($content_id, $item_id, $sku, $content, $pagetitle, $longtitle, $description, $published, $parent, $richtext, $template, $searchable, $cacheable, $menutitle){
		$cont = $content;

		$this->db->upd($this->config['pfx'], 'site_content', 'pagetitle="' . $pagetitle . '", longtitle="' . $longtitle . '", description="' . $description . '", template=' . $template . ', content="' . $content . '", menutitle="' . $pagettitle .'"', 'id=' . $content_id);
	    $this->db->upd($this->config['pfx'], 'site_tmplvar_contentvalues', 'tmplvarid=4508, contentid=' . $content_id . ', value="' . $sku . '"');	
		echo "<br><br>TESTESTTEST<br><br>";
	}

		
/**
 * This will add a new item to the ModX content page database (site_content)
 * 
 * @param       pagetitle     =   Title of the page
 * @param       longtitle     =   Long title of the page
 * @param       description   =   Description of the page
 * @param       published     =   Boolean 1 Published / 0 Not
 * @param       parent        =   Integer FK relationship to parent document 49 for us
 * @param       richtext      =   Boolean 1 RT Editor / 0 Plain
 * @param       template      =   Integer FK relationship to template 7 for product template
 * @param       searchable    =   Boolean 1 Searchable / 0 Not
 * @param       cacheable     =   Boolean 1 Cacheable / 0 Not
 * @param       menutitle     =   Title to show in the menu 
 * @param		trxntype	  =	  The trxntype (UPDATED OR NEW)
 * 
 * @param	The MySQL ID of the content page that was just added to the database
 **/
	private function addContainer($item_id, $sku, $content, $pagetitle, $longtitle, $description, $published, $parent, $richtext, $template, $searchable, $cacheable, $menutitle){
		$cont = $content;
        $timeraw=time();

		$this->db->ins($this->config['pfx'], 'site_content', 'type, contentType, pagetitle, longtitle, description, published, parent, richtext, template, searchable, cacheable, createdby, createdon, content, menutitle', '"document", "text/html", "' . $pagetitle . '", "' . $longtitle . '", "' . $description .'", ' . $published . ', ' . $parent . ', ' . $richtext . ', ' . $template . ', ' . $searchable . ', ' . $cacheable . ', 1, ' . $timeraw . ', "' . $cont . '", "' . $menutitle . '"');
        $result = $this->db->sel($this->config['pfx'], 'site_content', 'id', 'pagetitle="' . $pagetitle . '" AND longtitle="' . $longtitle . '" AND createdon=' . $timeraw);;
       	$row = $result[0];

	    $this->db->ins($this->config['pfx'], 'site_tmplvar_contentvalues', 'tmplvarid, contentid, value', '4508, ' . $row['id'] . ', "' . $sku . '"');
	    return $row['id'];		
	}
		
/**
 * This is used to write an item to the database.  This might be utilized by external applications to produce a record in 
 * catalog (or update / delete) an existing record.
 * 
 *  @param      num                 =   Item Number
 *  @param      name                =   Item Name
 *  @param      amt                 =   Item Cost
 *  @param      hazmat              =   Hazardous Materials Add'l Shipping Cost
 *  @param      oversized           =   Oversized Item Shipping Cost
 *  @param      shoppingenabled     =   BOOL 1=SHOP ENABLED 0=SHOP DISABLED
 *  @param      quoteenabled        =   BOOL 1=QUOTE ENABLED 0=QUOTE DISABLED
 *  @param      disabled            =   OPP OF THE VAR I TAKE IN THE PARENT METHOD...$active=0 --> $disabled=1
 *  @param      type                =   Trans Type
 * 
 * @return 	The MySQL ID of the item that was added to the database
 **/
	public function writeItemToDB($num, $name, $sku, $shortdescription, $amt, $hazmat, $oversized, $shoppingenabled, $quoteenabled, $disabled, $type){
        if ($type=='NEW'){
            $this->db->ins($this->config['fpx'], 'items', 'name, sku, amount, hazmat, oversized, shoppingenabled, quoteenabled, disabled', '"' . $name . '", "' . $itemsku  . '", ' . $amt . ', ' . $hazmat . ', ' . $oversized . ', ' . $shoppingenabled . ', ' . $quoteenabled . ', ' . $disabled);
        } else if ($type=='UPDATED'){
            $result = $this->db->sel($this->config['fpx'], 'items_audit', 'items_id', 'id=' . $num); 
            $row = $result[0];
			
			$this->db->upd($this->config['fpx'], 'items', 'name="' . $name . '", sku="' . $sku . '", amount=' . $amt . ', description="' . $shortdescription . '", hazmat=' . $hazmat . ', oversized=' . $oversized . ', shoppingenabled=' . $shoppingenabled . ', quoteenabled=' . $quoteenabled . ', disabled=' . $disabled, 'id=' . $row['items_id']);
        } else if ($type=='DELETE'){
            $this->db->upd($this->config['fpx'], 'items', 'disable=1', 'id=' . $num);
        }
		
        if ($type=='NEW'){
            $result = $this->db->sel($this->config['fpx'], 'items', 'id', 'name="' . $name . '"');
            $row = $result[0];
            $itemid = $row['id'];
			
            $this->db->ins($this->config['fpx'], 'items_audit', 'items_id, sku, name, description, amount, hazmat, oversized, disabled, shoppingenabled, quoteenabled, status', $itemid . ', "' . $sku . '", "' . $name . '", "' . $shortdescription . '", ' . $amt . ', ' . $hazmat . ', ' . $oversized . ', ' . $disabled . ', ' . $shoppingenabled . ', ' . $quoteenabled . ', "NEW"');
        } else if ($type=='UPDATED'){
            $result = $this->db->sel($this->config['fpx'], 'items', 'id', 'name="' . $name . '"');
            $row = $result[0];
            $itemid = $row['id'];
            $this->db->upd($this->config['fpx'], 'items_audit', 'sku="' . $sku . '", name="' . $name . '", description="' . $shortdescription . '", amount=' . $amt . ', hazmat=' . $hazmat . ', oversized=' . $oversized . ', disabled=' . $disabled . ', shoppingenabled=' . $shoppingenabled . ', quoteenabled=' . $quoteenabled . ', status="UPDATED"', 'id=' . $num);
	    }																					
		return $itemid;
	}
	
/**
 * This function will return in <option></option> format the list 
 * of configured payment types during customer checkout
 * 
 * @return	Returns the available payment types in <option></option> tags
 * 
 **/
	public function paymentTypes(){
		$result = $this->db->sel($this->config['fpx'], 'config_values', 'optval', 'optname="authorize_enabled"');
		$gway1 = $result[0];
		
		$result = $this->db->sel($this->config['fpx'], 'config_values', 'optval', 'optname="google_enabled"');
		$gway2 = $result[0];

		$result = $this->db->sel($this->config['fpx'], 'config_values', 'optval', 'optname="paypal_enabled"');
		$gway3 = $result[0];

		$gtways = '';
		if ($gway1['optval'] == 'ENABLED'){
			$gtways.= "\n\t<option value=\"CC\">Credit Card via Authorize.net</option>\n";
		}
		if ($gway2['optval'] == 'ENABLED'){
			$gtways.="\t<option value=\"GOOG\">Google Checkout</option>\n";
		}
		if ($gway3['optval'] == 'ENABLED'){
			$gtways.="\t<option value=\"PAYPAL\">Paypal</option>\n";
		}
		return $gtways;				   
	}
		
/**
 * This function implements the Authorize.NET payment gateway
 * 
 * @param	custarr	=	Array of customer information
 * @param	cc		=	Array of credit card information
 * @param	amount	=	Amount to charge to the customer's credit card
 * 
 * NOTE:  When j is greater than 69, the fields are custom fields which
 * 		  can be defined by the merchant.
 * 
 * @return	Response array containing authorization information and status.
 **/
	private function authorizeDotNetCheckout($custarr, $cc, $amount){
        $DEBUGGING                  = 1;
        $TESTING                    = 1;
        $ERROR_RETRIES              = 2;
	
        $auth_net_login_id          = $this->config['authorize_user'];  
        $auth_net_tran_key          = $this->config['authorize_trxnkey']; 
        $auth_net_url               = $this->config['authorize_url'];
        $authnet_values             = array
		  ( "x_login"               => $auth_net_login_id,
            "x_version"             => '3.1',
            "x_delim_char"          => '|',
            "x_delim_data"          => 'TRUE',
            "x_url"                 => 'FALSE',
            "x_type"                => 'AUTH_CAPTURE',
            "x_method"              => 'CC',
            "x_tran_key"            => $auth_net_tran_key,
            "x_relay_response"      => 'FALSE',
            "x_card_num"            => $cc['cardnum'],
            "x_exp_date"            => $cc['expdate'],
            "x_description"         => $this->config['company_name'],
            "x_amount"              => $amount,
            "x_first_name"          => $custarr['fname'],
            "x_last_name"           => $custarr['lname'],
            "x_address"             => $custarr['address'],
            "x_city"                => $custarr['city'],
            "x_state"               => $custarr['state'],
            "x_zip"                 => $custarr['zip'],);
		
		$feilds = '';
		
        foreach( $authnet_values as $key => $value ) $fields .= "$key=" . urlencode( $value ) . "&";
            $ch = curl_init($this->config['authorize_url']);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim( $fields, "& " ));
            //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            $resp = curl_exec($ch);
            curl_close ($ch);
            $text = $resp;
            $h = substr_count($text, "|");
            $h++;
            $returnresp['gway']=1;
            $returnresp['approval']='APPROVED';
            for($j=1; $j <= $h; $j++){
				$p = strpos($text, "|");
				
				if ($p === false) {
	                if($j>=69){
                    }else{
                    }
                } else {
 					$p++;
                    $pstr = substr($text, 0 , $p);
														   
                    $pstr_trimmed = substr($pstr, 0, -1);
															   
                    if($pstr_trimmed==''){
						$pstr_trimmed='NO VALUE RETURNED';
	                }
	
                    switch($j){
                        case 1:
                            if($pstr_trimmed=="1"){
	                            $returnresp['approval']='APPROVED';
                            }elseif($pstr_trimmed=="2"){
								$returnresp['approval']='DECLINED';
                            }elseif($pstr_trimmed=="3"){
                                $returnresp['approval']='ERROR';																				                            }
                        break;
						
                        case 5:
                            $returnresp['authcode']=$pstr_trimmed;
                        break;
						
                        case 7:
                            $returnresp['trxnid']=$pstr_trimmed;
                        break;
						
                        default:						
                            if($j>=69){
                            }
                            else{
                            }
                        break;
                    }
                }
           }
        return $returnresp;
	}
		
/**
 * This function is designed to create the hidden fields required for a POST back google checkout.  When a customer
 * chooses google during the checkout process, this will generate a button with the appropriate merchant ID, tax rate, etc.
 * 
 * @param	sessionid	=	Session ID of the user
 * 
 * Note...to implement this correctly, you need to have a web service with 128bit TLS encryption running to receive
 * a notification callback from Google.  This is basically an XML parser that listens for the response, most likely
 * SOAP.  I will implement one for ITema when we have a certificate to sign our server with, but for now, you'll have
 * to go ensure that the payment was processed. 
 **/
	public function googleCheckout($sessionid){
        $merchantid = $this->config['google_merchantid'];
        $webserver = $this->config['google_url'];
        $shipmethod = "UPS Ground";
        $shipprice = $this->getShip($sessionid) + $this->getHandle($sessionid);
        $taxrt = floatval($this->config['tax_percentage']);
        $taxstate = $this->config['tax_state'];

        echo '<form method="POST" action="https://' . $webserver. '/checkout/cws/v2/Merchant/' . $merchantid . '/checkoutForm" accept-charset="utf-8" >' . "\n";
	
        // Go grab the items from the customer's cart
        $result = $this->db->sel($this->config['fpx'], 'cart_header', 'id, fname, lname, addr1, addr2, city, state, zip, cust_id',  'session_id="' . $sessionid . '"');
        $hdr = $result[0];
		
        $result = $this->db->sel($this->config['fpx'], 'cart_detail as B INNER JOIN ' . $this->config['fpx'] . 'items as A ON item_id = A.id', 'A.id, A.name, A.description, quantity, options, optionsprice, totalprice', 'header_id=' . $hdr['id']);
	
        for ($i=0; $i < sizeof($result); $i++){
            $row = $result[$i];
            $k = $i + 1;
            echo '<input type="hidden" name="item_name_' . $k .'" value="' . $row['A.name'] . '"/>' . "\n";
            echo '<input type="hidden" name="item_description_' . $k . '" value="' . $row['A.description'] . '<br />Options: ' . $row['quantity'] . '<br />Options Price: ' . $row['options'] . '"/>' . "\n";
            echo '<input type="hidden" name="item_quantity_' . $k . '" value="' . $row['quantity'] . '"/>' . "\n";
            echo '<input type="hidden" name="item_price_' . $k . '" value="' . (floatval($row['totalprice']) / floatval($row['quantity'])) . '"/>' . "\n";
        }

        echo '<input type="hidden" name="ship_method_name_1" value="' . $shipmethod . '"/>' . "\n";
        echo '<input type="hidden" name="ship_method_price_1\" value="' . $shipprice . '"/>' . "\n";
        echo '<input type="hidden" name="tax_rate" value="' . $taxrt . '"/>' . "\n";
        echo '<input type="hidden" name="tax_us_state" value="' . $taxstate . '"/>' . "\n";
		echo '<input type="hidden" name="_charset_" />' . "\n";
        echo '<input type="image" name="Google Checkout" alt="Fast checkout through Google" src="http://"' . $webserver . '/checkout/buttons/checkout.gif?merchant_id=' . $merchantid . '&w=180&h=46&style=trans&variant=text&loc=en_US" height="46" width="180"/>' . "\n";
		
        echo '</form>';																																																							 
	}
		
/**
 * This function is designed to create the hidden fields required for a POST back paypal checkout.  When a person chooses
 * to checkout via paypal, this will auto-generate the button and fields which are required to send to PayPals website.
 * 
 * @param	sessionid		=	Session ID of the user
 * 
 * NOTE:  Like the Google Checkout gateway, a callback gateway (SOAP server) is required to receive a confirmation of payment
 * back from the gateway when the transaction is completed.
 **/
	public function paypalCheckout($sessionid){
        $merchantid = $this->config['paypal_merchantid'];
        $webserver = $this->config['paypal_url'];
        $shipmethod = 'UPS Ground';
        $shipprice = $this->getShip($sessionid);
        $handleprice = $this->getHandle($sessionid);
        $snh = $shipprice + $handleprice;
        $taxrt = $this->config['tax_percentage'];
        $tax = $this->getTax($sessionid);
        $ctry = $this->config['company_country'];
	
        echo '<form method="POST" action="https://' . $webserver. '/cgi-bin/webscr/">';

        echo '<input type="hidden" name="cmd" value="_cart">';
        echo '<input type="hidden" name="upload" value="1">';
        echo '<input type="hidden" name="business" value="' . $merchantid . '">';
        // Go grab the items from the users cart
			
        $result = $this->db->sel($this->config['fpx'], 'cart_header' , 'id, fname, lname, addr1, addr2, city, state, zip, cust_id' , 'session_id="' . $sessionid . '"');
        $hdr = $result[0];

        $result = $this->db->sel($this->config['fpx'], 'cart_detail as B INNER JOIN ' . $this->config['fpx'] . 'items as A on item_id = A.id', 'A.id, A.name, A.description, quantity, options, optionsprice, totalprice', 'header_id=' . $hdr['id']);
		$k=0;
        for ($i=0; $i < sizeof($result); $i++){
            $row = $result[$i];
            $k = $i + 1;
            echo '<input type="hidden" name="item_name_' . $k . '" value="' . $row['name'] . '">';
            echo '<input type="hidden" name="quantity_' . $k . '" value="' . $row['quantity'] . '">';
            echo '<input type="hidden" name="amount_' . $k . '" value="' . (floatval($row['totalprice']) / floatval($row['quantity'])) . '">';
        }

        echo '<input type="hidden" name="tax_cart" value="' . $tax . '">';
        echo '<input type="hidden" name="handling_cart" value="' . $snh . '" />';
        echo '<input type="hidden" name="first_name" value="' . $hdr['fname'] . '" />';
        echo '<input type="hidden" name="last_name" value="' . $hdr['lname'] . '" />';
        echo '<input type="hidden" name="address1" value="' . $hdr['addr1'] . '" />';
        echo '<input type="hidden" name="address2" value="' . $hdr['addr2'] . '" />';
        echo '<input type="hidden" name="city" value="' . $hdr['city']. '" />';
        echo '<input type="hidden" name="state" value="' . $hdr['state'] . '" />';
        echo '<input type="hidden" name="zip" value="' . $hdr['zip'] . '" />';
        echo '<input type="image" name="Paypal Checkout" alt="Fast checkout through Paypal" src="assets/snippets/shoppingCart/paypal_button.gif">';
        echo '</form>';
	}
		
/**
 * This function will create a new option for a particular item.
 * It will also create a CHUNK in modx, that way the option can
 * easily be displayed on the item page or added to a template
 *
 * PREREQ:  The item record must exist and the list for the item's
 *          options should already be created before calling this
 *          method.
 *
 * @param       listid      =   ID of the list which will provide options for
 *                              the item.
 * @param       name        =   Name of the option
 * @param       renderas    =   How to render the option (CHECK, TEXT, TEXTAREA,
 *                              RADIO, MULTI, SELECT)
 * @param       htmlclass   =   CSS class for the option
 * @param       size        =   Size of the field (also used for num of rows for textarea)
 * @param       length      =   Mostly used for storing the number of columns
 * @param       deflt       =   Default option id or text to display
 **/
	public function createOption($listid, $name, $renderas, $htmlclass, $size, $length, $deflt){
        $itemid = 0;
        if ($renderas=='DROP'){
            $renderas='SELECT';
        }
		
		$this->db->ins($this->config['fpx'], 'options', 'item_id, lists_id, name, renderas, htmlclass, size, length, deflt', $itemid . ', ' . $listid . ', "' . $name . '", "' . $renderas . '", "'. $htmlclass . '", ' . floatval($size) . ', ' . floatval($length) . ',"' . $deflt . '"');

        $edit_type = 0;
        $category = 20;
        $cache_type = 0;
        $locked = 0;

        $result = $this->db->sel($this->config['pfx'], 'site_htmlsnippets', 'id', 'name="' . $name . '"');

        if (sizeof($result)==0){
            //echo "NO RESULTS RETURNED, ADDING HTML CHUNK";
					
            $snippet = '[[kiwee? &elem=OPTIONS&optionname=' . $name . ']]';
            $this->db->ins($this->config['pfx'], 'site_htmlsnippets', 'name, editor_type, category, cache_type, snippet, locked', '"' . $name .'", ' . $edit_type . ', ' . $category . ', ' . $cache_type . ', "' . $snippet . '", ' . $locked . '"');
        }		
	}
		
/**
 * This function will update an exisiting option record
 *
 *   PREREQ: The lists of options should already be created before calling this
 *           method.
 *
 * @param       optionid    =   ID of the option to render
 * @param       listid      =   ID of the list which will provide options for
 *                              the item.
 * @param       name        =   Name of the option
 * @param       renderas    =   How to render the option (CHECK, TEXT, TEXTAREA,
 *                              RADIO, MULTI, SELECT)
 * @param       htmlclass   =   CSS class for the option
 * @param       size        =   Size of the field (also used for num of rows for textarea)
 * @param       length      =   Mostly used for storing the number of columns
 * @param       deflt       =   Default option id or text to display
 **/
	public function updateOption($optionid, $listid, $name, $renderas, $htmlclass, $size, $length, $deflt){
		// All other names passed through renderas I take at face value.  Syntax change though for this one.
        if ($renderas=='DROP'){
            $renderas='SELECT';
        }
		$this->db->upd($this->config['fpx'], 'options', 'lists_id=' . $listid . ', name="' . $name . '", renderas="' . $renderas . '", htmlclass="' . $htmlclass . '", size="' . floatval($size) . ", length=" . floatval($length). '", deflt="' . $deflt . '"', 'id=' . $optionid);		
	}

/**
 * This function is designed to delete an option from the database.
 * 
 * @param		id		=	ID of the option to delete
 **/
	public function deleteOption($id){
        $this->db->del ($this->config['fpx'], 'options', 'id=' . $id);		
	}
		
/**
 * This will create a new header for a blank list.  The list is populated by adding rows in the 
 * lists_options table with FK relationships to the lists table.
 * 
 * @param	name		=	Name of the list
 * @param	description	=	Description of the list
 * 
 * @return	MySQL ID of the list that was created
 **/
    public function createList($name, $description){
        $this->db->ins($this->config['fpx'], 'lists', 'name, description', '"' . $name . '", "' . $description . '"');

        $result = $this->db->sel($this->config['fpx'], 'lists', 'id', 'name="' . $name . '"');
        $row = $result[0];

        return $row['id'];
    }
		
/**
 * This method is designed to update the properties of a list
 * 
 * @param	id			=	ID of the list from MySQL
 * @param	name		=	Updated name of the list
 * @param	description	=	Updated description of the list	
 **/
	public function updateList($id, $name, $description){
		$this->db->upd($this->config['fpx'], 'lists', 'name="' . $name . '", description="' . $description . '"', 'id=' . $id);
	}
		
/**
 * This function is designed to update a list options
 * 
 * @param	id		=	ID of the list option
 * @param	name	=	Name of the list option
 * @param	value	=	Value of the list option
 * @param	offset	=	Price Offset of the list option
 **/
	public function deleteList($id){
        $this->db->del($this->config['fpx'], 'lists_options', 'lists_id=' . $id);
        $this->db->del($this->config['fpx'], 'lists', 'id=' . $id);
	}
		
/**
 * This will get the PK ID's of all options that are to be displayed for a
 * particular item.  This will return an associative indexed array.
 * 
 * @param		itemid	=	This is the itemid of the item for which we want to
 * 							obtain options.
 * 
 * @return	Associative array of all of the options for a particular item
 **/
	public function getAllOptions($itemid){
		$result = $this->db->sel($this->config['fpx'], 'options', 'lists_id, name, renderas, htmlclass, size, length, deflt', 'item_id=' . $itemid);
        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $opts[$i]['lists_id'] = $row['lists_id'];
            $opts[$i]['name'] = $row['name'];
            $opts[$i]['renderas'] = $row['renderas'];
            $opts[$i]['htmlclass'] = $row['htmlclass'];
            $opts[$i]['size'] = $row['size'];
            $opts[$i]['length'] = $row['length'];
            $opts[$i]['default'] = $row['deflt'];
        }

        return $opts;		
	}
	
/**
 * This will return an option with a particular
 *
 * @param       name    =   The name of the option to retrieve
 **/
    function getoption($item_id){
		$result = $this->db->sel($this->config['fpx'], 'options', 'lists_id, name, renderas, htmlclass, size, length, deflt', 'id=' . $item_id);
		$row = $result[0];
		
        $opts['listid'] = $row['lists_id'];
        $opts['name'] = $row['name'];
        $opts['renderas'] = $row['renderas'];
        $opts['htmlclass'] = $row['htmlclass'];
        $opts['size'] = $row['size'];
        $opts['length'] = $row['length'];
        $opts['default'] = $row['deflt'];
		
        return $opts;
	}

/**
 * This will return the option with the specified name
 * 
 * @param	name	=	The name of the option to retrieve
 * 
 * @return	An array with the properties for the option which
 * 			was retrieved from the database.
 **/
	public function getOptionByName($name){
		$result = $this->db->sel($this->config['fpx'], 'options', 'lists_id, renderas, htmlclass, size, maxlen, rows, cols, deflt' , 'name="' . $name . '"');
        $row = $result[0];
        $opts['listid'] = $row['lists_id'];
        $opts['renderas'] = $row['renderas'];
        $opts['htmlclass'] = $row['htmlclass'];
        $opts['size'] = $row['size'];
        $opts['maxlen'] = $row['maxlen'];
		$opts['rows'] = $row['rows'];
		$opts['cols'] = $row['cols'];
        $opts['deflt'] = $row['deflt'];
 
		return $opts;		
	}
		
/**
 * This method is for the admin interface.  It is only designed to return the names of all lists.
 * 
 * @return	An associative array with the list ids, names and descriptions
 **/
	public function getAllLists(){
        $result = $this->db->sel($this->config['fpx'], 'lists', 'id, name, description');
		
		for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $lists[$i]['id'] = $row['id'];
            $lists[$i]['name'] = $row['name'];
            $lists[$i]['description'] = $row['description'];
        }
        return $lists;		
	}
		
/**
 * This function is designed to return the name and description of a list.
 * 
 * @param	listid		=	The id of the list to retrieve
 * 
 * @return 	The name and description of a list with a given id
 **/
	public function getListProperties($listid){
        $result = $this->db->sel($this->config['fpx'], 'lists', 'name, description' , 'id=' . $listid);
        $row = $result[0];
        $listproperties['name'] = $row['name'];
        $listproperties['description'] = $row['description'];

        return $listproperties;
	}

/**
 * This function is designed to return the name, description and price offset of a given list option.
 * 
 * @param	listoptionid	= The id of the list option to return
 * 
 * @return	The name, description, and price offset of the list option in an array
 **/
	public function getListOptionProperties($listoptionid){
        $result = $this->db->sel($this->config['fpx'], 'lists_options', 'name, value, priceoffset', 'id=' . $listoptionid);
		$row = $result[0];
		
        $opt['name'] = $row['name'];
        $opt['value'] = $row['value'];
        $opt['offset'] = $row['priceoffset'];
		
        return $opt;
	}

/**
 * This function will get all list items in a particular list
 * 
 * @param	listid	=	This is the id of the list for which we want
 * 						to retrieve options.
 * 
 * @param	The id, name, value and price offset for all items on a particular list.
 **/
  // edited by Bright @ 20080729 added a memo collum in "lists_options" table, add a sellect in this function
	public function getListOptions($listid){
        $result = $this->db->sel($this->config['fpx'], 'lists_options', 'id, name, value, priceoffset, memo', 'lists_id=' . $listid);

		$opts = array();
		for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $opts[$i]['id'] = $row['id'];
            $opts[$i]['name'] = $row['name'];
            $opts[$i]['value'] = $row['value'];
            $opts[$i]['priceoffset'] = $row['priceoffset'];
			$opts[$i]['memo'] = $row['memo'];
        }
 
		return $opts;
	}

/**
 * This function will get all list items for a particular list by the name of the list
 * 
 * @param	name	=	The name of the list
 * 
 * @return	The id, name, value and price offset of the list items for the give list
 **/
	public function getListOptionsByName($name){
        $result = $this->db->sel($this->config['fpx'], 'lists', 'id', 'name="' . $name . '"');
        $row = $result[0];
        $result = $this->db->sel($this->config['fpx'], 'lists_options', 'id, name, value, priceoffset', 'lists_id=' . $row['id']);
		
        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $opts[$i]['id'] = $row['id'];
            $opts[$i]['name'] = $row['name'];
            $opts[$i]['value'] = $row['value'];
            $opts[$i]['priceoffset'] = $row['priceoffset'];
        }

		return $opts;
	}
		
/**
 * This function will retrieve the details of a list item by using it's MySQL ID
 * 
 * @param	id	=	The id of the list item to return
 * 
 * @return	The details for a given list item in an array
 **/

	public function getListOption($id){
        $result = $this->db->sel($this->config['fpx'], 'lists_options', 'name, value, priceoffset', 'id=' . $id);
        $row = $result[0];
		
        $opts['name'] = $row['name'];
        $opts['value'] = $row['value'];
        $opts['priceoffset'] = $row['priceoffset'];


        return $opts;		
	}
		
/**
 * This function is designed to add a list item associated with a given list
 * 
 * @param       listid  =   id of the list to associate with this option
 * @param       name    =   Name of the option to add
 * @param       value   =   Value of the option to add
 * @param       offset  =   Offset of the option to add
 **/
	public function createListOption($listid, $name, $value, $offset){
		$this->db->ins($this->config['fpx'], 'lists_options', 'lists_id, name, value, priceoffset', $listid . ', "' . $name. '", "' . $value . '", "' . $offset . '"');
	}
	
/**
 * This function is designed to update a list option
 * 
 * @param 	id			=	ID of the list option
 * @param	name		=	Name of the list option
 * @param	value		=	Value of the list option
 * @param	offset		=	Price Offset of the list option
 **/
	function updateListOption($id, $name, $value, $offset){
		$offsetfloat = floatval($offset);
		$this->db->upd($this->config['fpx'], 'lists_options', 'name="' . $name . '", value="' . $value . '", priceoffset=' . $offsetfloat, 'id=' . $id);
	}
		
/**
 * This function is designed to delete an item from a specified list
 * 
 * @param	listoptionid	=	The id number of the list item to delete
 **/
	public function deleteListOption($listoptionid){
		$this->db->del($this->config['fpx'], 'lists_options', 'id=' . $listoptionid);;		
	}
		
/**
 * This function is designed to interface with renderOption to produce all of the options
 * associated with an item.
 * 
 * @param	itemid	=	The id of the item to find options for
 * 
 * @return	The div which contains all of the options for an item.
 **/
	public function populateOptionsArea($itemid, $layout){
	
	
        $result = $this->db->sel($this->config['fpx'], 'items_options', 'options_id', 'item_id=' . $itemid . ' ORDER BY id');
		$size = sizeof($result);
		switch($layout){
			case "vertical":
				for ($i=0; $i<sizeof($result); $i++){
					$row = $result[$i];
       	     		$res = $this->db->sel($this->config['fpx'], 'options', 'name, renderas', 'id=' . $row['options_id']);
            		$rw = $res[0];
            		$hiddenopts .= $rw['name'] . ':' . $rw['renderas'] . '||';
            		$opts .= '<div class="itemoptions" style="float:right; width: 60%; padding-bottom: 5px; padding-top: 5px;">' . $this->renderOption($itemid, $rw['name'],$i, $size) . '</div>';
            		$opts .= '<div class="itemoptionslabel" style="float:left; width: 40%">' . $rw['name'] . ':  </div>';
					
					//add a hidden text area to handel all the option prices
					$opts .= '<input type="hidden" id="' . $i . 'newoptionprice" name="' . $i . 'newoptionprice" size="20">';
					
					//onchange="previewprice(\''.$currate.'\',\''.$size.'\')"

					
        		}
			break;
		}
        
		$trimmedopts = substr($hiddenopts, 0, strlen($hiddenopts)-2);
        echo '<input type="hidden" id="itemoptsstr" name="itemoptsstr" value="' . $trimmedopts . '" />';
		
        return $opts;
	}
		
/**
 * This function will produce a quantity field with the correct validation (integer or float)
 * 
 * @param	itemid	=	The id of the item to produce a box for.
 * 
 * @return	input field for the quantity
 **/
	public function displayQuantity($itemid){
		if ($this->config['cart_enabled'] == 'ENABLED'){
			echo '<input type="text" id="qtytoenter" name="qtytoenter" size=5 value="1">';	
		} else {
			echo '<input type="text" id="qtytoenter" name="qtytoenter" size=5 value="" disabled>';	
		}
	}
		
/**
 * This function is designed to render an option when it received the itemid and name
 * of the option.  It allows you to choose from several different HTML entities for
 * display.  IE:  RADIO, SELECT, MULTI, CHECK, TEXTAREA OR TEXT
 * 
 * NOTE:  These are stores in the database header table for the option.
 * 
 * @param	optionname	=	Name of the option to render.
 * @param	itemid		=	The id of the item to get options for
 *  //added by Bright @ 20080801 
  * @param	optionnum		=	the count of the options
 * 
 * @return 	The HTML code to produce the given HTML render of an option
 **/
	private function renderOption($itemid, $optionname, $optionnum, $size){
        $optioninfo = $this->getOptionByName($optionname);
        $opts = $this->getListOptions($optioninfo['listid']);
        $type = strtolower($optioninfo['renderas']);
		
		$curriso = $_SESSION['CURRENCY'];
		$currate = $this->getCurRate($curriso);
		$cursym = $this->getCurSym($curriso);
		
		
		
        if (($type=='radiobutton') || ($type=='radio')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
            for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['id']==$optioninfo['deflt']){$sel="checked";}
                $opt .= '<input ' . $sel . ' class="' . $optioninfo['htmlclass'] . '" type="radio" id="' . $optionname .  '" name="' . $optionname . '" value="' . $opts[$i]['id'] . '" OnClick="updateprice(\'radio\',\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\', \'' . $opts[$i]['priceoffset'] . '\');" ' . $dis . '>' . $opts[$i]['name'] .  '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '<br />' . "\n";
                $sel='';
            }
			//newoptionprice(\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')			
			//newoptionprice(\''.$type.'\',\'' . $optionname . '\', \'' . $opts[$i]['priceoffset'] . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')
			//updateprice(\'radio\',\'' . $optionname . '\', \'' . $opts[$i]['priceoffset'] . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')
/**	

            for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['name']==$optioninfo['deflt']){$sel="checked";}
                $opt .= '<input ' . $sel . ' class="' . $optioninfo['htmlclass'] . '" type="radio" id="' . $optionname .  '" name="' . $optionname . '" value="' . $opts[$i]['id']. '||'. $opts[$i]['priceoffset'].'" onClick="newoptionprice(\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')" ' . $dis . '>' . $opts[$i]['name'] .  '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '<br />' . "\n";
                $sel='';
            }

		

**/		
			
        } else if (($type=='dropdown') || ($type=='select') || ($type=='drop')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
		    $opt .= '<select id="' . $optionname . '" name="' . $optionname . '" class="' . $optioninfo['htmlclass'] . '"		onClick="updateprice(\'drop\',\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')">' . "\n";

			for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['id']==$optioninfo['deflt']){$sel='selected';}
                $opt .= "\t" . '<option ' . $sel . ' class="' . $optionname . '-row-' . $i . '" value="' . $opts[$i]['id']. '||'. $opts[$i]['priceoffset'].'" ' . $dis . '>' . $opts[$i]['name'] . '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '</option>' . "\n";
                $sel='';
			}
			
			
			/**
			for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['name']==$optioninfo['deflt']){$sel='selected';}
                $opt .= "\t" . '<option ' . $sel . ' class="' . $optionname . '-row-' . $i . '" value="' . $opts[$i]['id']. '" OnClick="document.getElementById(\'' . $optionname . '\').selectedIndex=' . $i . '; updateprice(\'' . $optionname . '\', ' . $opts[$i]['priceoffset'] . ', \'drop\');" ' . $dis . '>' . $opts[$i]['name'] . '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '</option>' . "\n";
                $sel='';
			}
			**/
			
	        $opt .= '</select>' . "\n";						
	    } 
		
	
		// Edited by Bright @ 20080729 this will display a select and edit option, when user select an opinion the memo stored in the option will be displayed in the textarea, and people can edit the value to what they want
		else if (($type=='selectandedit')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
            $opt .= '<select id="' . $optionname . '" name="' . $optionname . '" class="' . $optioninfo['htmlclass'] . '"		onChange="selectandeditexplain(\''. $optionname . '\');updateprice(\'selectandedit\',\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')">' . "\n";
			
			for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['id']==$optioninfo['deflt']){$sel='selected';}
				
				//find $opts[$i]['memo']  see if it contain " if have replace them to &quot;
				$opts[$i]['memo']=str_replace('"','&quot;',$opts[$i]['memo']);
				
                $opt .= "\t" . '<option ' . $sel . ' class="' . $optionname . '-row-' . $i . '" value="' . $opts[$i]['id'].'||'. $opts[$i]['priceoffset'].'||' . $opts[$i]['memo']. '" '. $dis . '>' . $opts[$i]['name'] . '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '</option>' . "\n";
                $sel='';

			}
						
	        $opt .= '</select>' . "\n";			
			
			//start with the textarea
			$opt .= '<textarea id="' . $optionname . 'editarea" class="' . $optioninfo['htmlclass'] . '" name="' . $optionname . 'editarea" rows="' . $optioninfo['rows'] . '" cols="' . $optioninfo['cols'] . '" onkeyup="updateprice(\'selectandedit\',\'' . $optionname . '\',\''.$optionnum.'\',\'' . $currate . '\',\'' . $size . '\')" ' . $dis . '>' . "\n";
			$opt .= '</textarea><br/>';
			//text area to display the total char and extra price.
			$opt .= '<input type="text" id="' . $optionname . 'charcount" name="' . $optionname . 'charcount" size="20"><br/>'.$cursym.'<input type="text" id="' . $optionname . 'newprice" name="' . $optionname . 'newprice" size="10">'.$curriso.' will applied<br/>';
			


			
	    } 
		
		else if (($type=='multiselect') || ($type=='multi')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
            $opt .= '<select id="' . $optionname . '" name="' . $optionname . '" class="' . $optioninfo['htmlclass'] . '" multiple size=' . $optioninfo['size'] . ">\n";
			
			for ($i=0; $i < sizeof($opts); $i++){
                if ($opts[$i]['name']==$optioninfo['deflt']){$sel='selected';}
	                $opt .= "\t" . '<option ' . $sel. ' id="' . $optionname . '-' . $i . '" value="' . $opts[$i]['id'] . '" OnClick="updateprice("' . $optionname . '", ' . $opts[$i]['priceoffset'] . ', "multi" );" ' . $dis . '>' . $opts[$i]['name'] .  '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '</option><br />' . "\n";	                $sel='';
            }
            $opt .= '</select>' . "\n";
        } else if (($type=='checkbox') || ($type=='check')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
			for ($i=0; $i < sizeof($opts); $i++){
	           if ($opts[$i]['name']==$optioninfo['deflt']){$sel='checked';}													
               $opt .= '<input ' . $sel. ' id="' . $optionname . '-' . $i . '" class="' . $optioninfo['htmlclass'] . '" name="' . $optionname . '" type="checkbox" value="' . $opts[$i]['id'] . '" OnClick="updateprice("' . $optionname . '", ' . $opts[$i]['priceoffset'] . ', "check");" ' . $dis . '>' . $opts[$i]['name'] . '  ' . $this->priceOffsetDisplay($opts[$i]['priceoffset']) . '<br />' . "\n";
               $sel='';
           }			
		} else if (($type=='textarea')) {
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
            $opt .= '<textarea id="' . $optionname . '" class="' . $optioninfo['htmlclass'] . '" name="' . $optionname . '" rows="' . $optioninfo['rows'] . '" cols="' . $optioninfo['cols'] . '" ' . $dis . '>' . "\n";
            $opt .= '</textarea>';
        } else if (($type=='text')){
			if ($this->config['cart_enabled'] == 'DISABLED'){$dis="disabled";}
            $opt .= '<input type="text" id="' . $optionname . '" class="' . $optioninfo['htmlclass'] . '" name="' . $optionname . '" size=' . $optioninfo['size'] . ' maxlength=' . $optioninfo['maxlen'] . ' ' . $dis . '/>' . "\n";
        }

        return $opt;
	}
		
/**
 * This is a helper function to decide whether to display price offset or not;
 * 
 * The reson I broke this method out is so that it could be called in-line
 * when I render the option and so that it can be overridden easily by developers
 * (like the one who is probably reading this)
 * 
 * @param	poffset	=	Price offset
 * 
 * @return price if > zero else nothing
 **/
	private function priceOffsetDisplay($poffset){
	
$curriso = $_SESSION['CURRENCY']; 
$currate = $this->getCurRate($curriso);
$cursym = $this->getCurSym($curriso);
	
		$b = round($currate*$poffset);
         $num = $cursym."  ".number_format($b, 2)." ".$curriso;
			
        if ($poffset != 0.00){
            return "&nbsp;&nbsp;" . $num;
        }
	}
		
/**
 * This function is designed to return an associative array of information about a customer, including their ModX user information.
 * 
 * @param	id	=	The MySQL id of the customer in the customers table
 * 
 * @return	The customer information in an array format
 **/
	public function getCustInfo($id){
        $result = $this->db->sel($this->config['fpx'], 'customers', 'fname, lname, addr1, addr2, city, state, zip, phone_1, phone_2, ext_1, ext_2, fax, custid, companyname', 'id=' . $id);
        $row = $result[0];
		
        $cust['id'] = $id;
        $cust['fname'] = $row['fname'];
        $cust['lname'] = $row['lname'];
        $cust['addr1'] = $row['addr1'];
        $cust['addr2'] = $row['addr2'];
        $cust['city'] = $row['city'];
        $cust['state'] = $row['state'];
        $cust['zip'] = $row['zip'];
        $cust['phone_1'] = $row['phone_1'];
        $cust['phone_2'] = $row['phone_2'];
        $cust['ext_1'] = $row['ext_1'];
        $cust['ext_2'] = $row['ext_2'];
        $cust['fax'] = $row['fax'];
        $cust['custid'] = $row['custid'];
        $cust['companyname'] = $row['companyname'];

        $result = $this->db->sel($this->config['pfx'], 'web_users', 'username, password', 'id=' . $row['custid']);
        $row = $result[0];
        $cust['username'] = $row['username'];
        $cust['password'] = $row['password'];

        $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'failedlogincount, blocked, blockeduntil, logincount, comment', 'internalKey=' . $cust['custid']);
        $row = $result[0];
        $cust['failedlogincount'] = $row['failedlogincount'];
        $cust['blocked'] = $row['blocked'];
        $cust['blockeduntil'] = $row['blockeduntil'];
        $cust['logincount'] = $row['logincount'];
        $cust['commentssection'] = $row['comment'];

        return $cust;		
	}
		
/**
 * This function is designed to check whether there is a user in the system who is already using the username
 * that a person is trying to use to sign up for an account.
 * 
 * @param	username	=	The username the customer is attempting to use
 * 
 * @return	TRUE if dup is found, FALSE if username is OK
 **/
	public function checkUsername($username){
        $result = $this->db->sel($this->config['pfx'], 'web_users', 'id', 'username="' . $username . '"');

        if (sizeof($result) > 0){
			return 'TRUE';	
		} else {
			return 'FALSE';
		}
	}
		
/**
 * This function is designed to check whether there is a user in the system who already has registered the email address
 * that a person is trying to use to sign up for a new account.
 * 
 * @param	email	=	Email address that the customer is attempting to use
 * 
 * NOTE: TRUE if dup is found, FALSE if email is OK, INVALID if email is not
 *       correctly formatted.
 **/
	public function checkEmail($email){
        $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'email', 'email="' . $email . '"');

        if (ereg("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email)){
			if (sizeof($result) < 0){
				return 'TRUE';	
			} else {
				return 'FALSE';
			}
       	} else {
            return 'INVALID';
        }
	}

/**
 * This function is designed to update customer info stored in a couple tables within ModX
 *
 * @param   id                  =   Customer ID in MOdX Ecommerce
 * @param   intkey              =   Internal ModX ID
 *
 * //SELF EXPLANATORY - BASIC CUST INFO
 * @param   companyname
 * @param   fname
 * @param   lname
 * @param   addr1
 * @param   addr2
 * @param   city
 * @param   state
 * @param   zip
 * @param   phone_1
 * @param   phone_2
 * @param   ext_1
 * @param   ext_2
 * @param   fax
 *
 * @param   username            =   username of the person
 * @param   password            =   hex md5 hash of the new password
 *
 * @param   logincount          =   Number of logins
 * @param   failedlogincount    =   Number of times a user has failed during login (Set this to 0 too to unlock an account)
 * @param   blocked             =   BOOL (0=false || 1=true)
 * @param   blockeduntil        =   TimeStanp of sorts telling when a failed user can log in again (Set to 0 to reset)
 * @param   comment             =   Comment about the customer (Could be anything)
 **/
	public function updateCustInfo($id, $intkey, $companyname, $fname, $lname, $addr1, $addr2, $city, $state, $zip, $phone_1, $phone_2, $ext_1, $ext_2, $fax, $username, $password, $logincount, $failedlogincount, $blocked, $blockeduntil, $comment){
		// Update ITema customer's table
		$this->db->upd($this->config['fpx'], 'customers', 'companyname="' . $companyname . '", fname="' . $fname . '", lname="' . $lname . '", addr1="' . $addr1 . '", addr2="' . $addr2 . '", city="' . $city . '", state="' . $state . '", zip="' . $zip . '", phone_1="' . $phone_1 . '", phone_2="' . $phone_2 . '", ext_1="' . $ext_1 . '", ext_2="' . $ext_2 . '", fax="' . $fax . '"', 'id=' . $id);
		// Update ModX username and password
		$this->db->upd($this->config['pfx'], 'web_users', 'username="' . $username . '", password="' . $password . '"', 'id=' . $intkey);
		// Update OTHER ModX user attributes
		$this->db->upd($this->config['pfx'], 'web_user_attributes', 'logincount=' . $logincount . ', failedlogincount=' . $failedlogincount . ', blocked=' . $blocked . ', blockeduntil=' . $blockeduntil . ', comment="' . $comment . '"', 'internalKey=' . $intkey);
	}
		
/**
 * This is designed to return the details of an order by id
 * 
 * @param	id	=	MySQL id (Order ID)
 * 
 * @return	An array of information about the order retrieved.
 **/
	public function getOrderInfo($id){
        $result = $this->db->sel($this->config['fpx'], 'order_header', 'id, pay_id, cust_id, totshipping, tothandling, tax, total, subtotal, currency, currrate, paymentApproved, authCode, ponumber, status, orderitems, created, updated, shipfname, shiplname, shipaddr1, shipaddr2, shipcity, shipstate, shipzip, shipphone, shipext', 'id=' . $id);
        $row = $result[0];

        $ordinfo['id'] = $row['id'];
        $ordinfo['pay_id'] = $row['pay_id'];
        $ordinfo['cust_id'] = $row['cust_id'];
        $ordinfo['totshipping'] = $row['totshipping'];
        $ordinfo['tothandling'] = $row['tothandling'];
        $ordinfo['tax'] = $row['tax'];
        $ordinfo['total'] = $row['total'];
        $ordinfo['subtotal'] = $row['subtotal'];
		
		//edited by Bright @ 20080807
        $ordinfo['currency'] = $row['currency'];
        $ordinfo['currrate'] = $row['currrate'];

        $ordinfo['paymentApproved'] = $row['paymentApproved'];
        $ordinfo['authCode'] = $row['authCode'];
        $ordinfo['ponumber'] = $row['ponumber'];
        $ordinfo['status'] = $row['status'];
        $ordinfo['orderitems'] = $row['orderitems'];
        $ordinfo['created'] = $row['created'];
        $ordinfo['updated'] = $row['updated'];
        $ordinfo['shipfname'] = $row['shipfname'];
        $ordinfo['shiplname'] = $row['shiplname'];
        $ordinfo['shipaddr1'] = $row['shipaddr1'];
        $ordinfo['shipaddr2'] = $row['shipaddr2'];
        $ordinfo['shipcity'] = $row['shipcity'];
        $ordinfo['shipstate'] = $row['shipstate'];
        $ordinfo['shipzip'] = $row['shipzip'];
        $ordinfo['shipphone'] = $row['shipphone'];
        $ordinfo['shipext'] = $row['shipext'];
        
		$result = $this->db->sel($this->config['fpx'], 'pay_gateways', 'name', 'id=' . $ordinfo['pay_id']);
        $row = $result[0];

        $ordinfo['payment_name'] = $row['name'];
		
        $result = $this->db->sel($this->config['fpx'], 'customers', 'fname, lname, addr1, addr2, city, state, zip, phone_1, ext_1, phone_2, ext_2, fax, companyname, custid', 'id=' . $ordinfo['cust_id']);
        $row = $result[0];
		
        $ordinfo['fname'] = $row['fname'];
        $ordinfo['lname'] = $row['lname'];
        $ordinfo['addr1'] = $row['addr1'];
        $ordinfo['addr2'] = $row['addr2'];
        $ordinfo['city'] = $row['city'];
        $ordinfo['state'] = $row['state'];
        $ordinfo['zip'] = $row['zip'];
        $ordinfo['phone_1'] = $row['phone_1'];
        $ordinfo['ext_1'] = $row['ext_1'];
        $ordinfo['phone_2'] = $row['phone_2'];
        $ordinfo['ext_2'] = $row['ext_2'];
        $ordinfo['fax'] = $row['fax'];
        $ordinfo['companyname'] = $row['companyname'];
        $ordinfo['modxcustid'] = $row['custid'];

        $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'email', 'id=' . $ordinfo['modxcustid']);
        $row = $result[0];
        $ordinfo['email'] = $row['email'];

        return $ordinfo;
	}
		
/**
 * This function is designed to return the order statistics for the order maintenance admin page
 * 
 * @return	An array of the order stats information
 **/
	public function getOrderStats(){
        $result = $this->db->sel($this->config['fpx'], 'order_header', 'id, status');

        $ordstat['neworders'] = 0;
        $ordstat['cancelledorders'] = 0;
        $ordstat['updatedorders'] = 0;
        $ordstat['processedorders'] = 0;
        $ordstat['errororders'] = 0;
        $ordstat['backorders'] = 0;
        $ordstat['shippedorders'] = 0;
        $ordstat['totalorders'] = 0;		
		
        for($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            switch($row['status']){
                case "NEW":
                    $ordstat['neworders']++;
                break;
				
                case "CANCELLED":
                    $ordstat['cancelledorders']++;
                break;
							
  		        case "UPDATED":
  		            $ordstat['shippedorders']++;
                break;
						
                case "PROCESSING":
                    $ordstat['processedorders']++;
                break;
							
                case "SHIPPED":
                    $ordstat['shippedorders']++;
 	            break;
							
                case "BACKORDERED":
                    $ordstat['backorders']++;
                break;
						
                case "ERROR":
                    $ordstat['errororders']++;
                break;
            }
  	        $ordstat['totalorders']++;
        }
		
		$ordstat['totalorders']--;

        return $ordstat;
	}		
		
/**
 * This function is designed to return an array of item maintenance statistics
 * 
 * @return	An array of item statistics
 **/
	public function getItemStats(){
        $result = $this->db->sel($this->config['fpx'], 'items_audit', 'id, status');

        $itemstat="";

        $itemstat['newitems'] = 0;
        $itemstat['currentitems'] = 0;
        $itemstat['deleteditems'] = 0;
        $itemstat['updateditems'] = 0;
        $itemstat['newitems'] = 0;
        $itemstat['totalitems'] = 0;
		
        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            switch($row['status']){
                case "new":
                    $itemstat['newitems']++;
                break;
							
                case "current":
                    $itemstat['currentitems']++;
                break;
									
                case "updated":
                    $itemstat['updateditems']++;
                break;
									
                case "deleted":
                    $itemstat['deleteditems']++;
                break;
			}
			$itemstat['totalitems']++;
		}
        return $itemstat;
	}
		
/**
 * This function will check whether a user is a valid modx user and then make sure that
 * they have an ecomm account.  If they don't have either, false is returned.  If they
 * DO have both, true is returned.  If they don't have an ecomm account, I will make one
 * for them (simple update of modx_ecomm_customers
 *
 * @param   sessionid       =   Session ID of the user
 * @param   webshortname    =   ModX username logged in
 * @param   webinternalkey  =   ModX mySQL ID of the user logged in
 * @param   webemail        =   ModX email of the user logged in
 * @param   webvalid        =   Not sure, but I won't handle it for now.  I believe
 *                              (without research) that it is some form of session var
 *                              to identify the user as being a valid web user.  Perhaps
 *                              reversible encryption?
 * @param   webuser         =   Not sure, but I won't handle it for now.  I believe
 *                              (without research) that it is some form of session var
 *                              to identify the user as being a valid web user.  Perhaps
 *                              this is done with reversible encryption since I don't see
 *                              a translation table of sorts in the modx_ database.
 **/
	public function checkLogin($sessionid, $webshortname, $webinternalkey, $webemail, $webvalid, $webuser){
        // Check for valid data
        if ($webinternalkey!='' && $sessionid!='' && $webshortname!=''){
            $result = $this->db->sel($this->config['pfx'], 'web_users', 'username, password','id=' . $webinternalkey);
            $row = $result[0];

            $dbuser = $row['username'];
            $dbpass = $row['password'];
            // Check that the dbuser matches the clientside username
            if ($dbuser == $webshortname){
                $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'email, sessionid, phone, mobilephone, country, state, zip, fax, fullname', 'internalKey=' . $webinternalkey);
                $row = $result[0];

                $email=$row['email'];
                $dbsession = $row['sessionid'];
                $modxphone = $row['phone'];
                $modxmobilephone = $row['mobilephone'];
                $modxcountry = $row['country'];
                $modxstate = $row['state'];
                $modxzip = $row['zip'];
                $modxfax = $row['fax'];
                $modxfullname = $row['fullname'];

                // Check that client email and session info matches what is in the database
                if (($email==$webemail) && ($dbsession==$sessionid)){
                    // OK now we know the client is authenticated for ModX
                    // Lets make sure they have an ecomm account
                    $result = $this->db->sel($this->config['fpx'], 'customers', 'id', 'custid=' . $webinternalkey);
                    if (sizeof($result) > 0){
                        // YAY, the user is in both systems, you may pass...
                        return 'MATCH';
                    } else {
                        // In this case, the user might have existed pre-ecomm days, so
                        // we need to add their record
                        if ($modxcountry==223){
                            $modxcountry='USA';
                        }{
                            $modxcountry='';
                        }// Sorry, everyone else will have to add their own to this
                        $this->db->ins($this->config['fpx'], 'customers', 'fname, state, country, zip, phone_1, phone_2, fax, custid', '"' . $modxfullname . '", "' . $modxstate . '", "' . $modxcountry . '", "' . $modxzip . '", "' . $modxphone . '", "' . $modxmobilephone . '", "' . $modxfax . '", ' . $webinternalkey);
                        return 'MATCH';
                    }

                } else {
                    // client-side email matches a record, but their sessionid doesn't match the db value
                    return 'STALESESSION';
                }
            }else {
                // client-side username didn't match what was in the database
                return 'TRYAGAINORCREATE';
            }
        } else {
            // client-side didn't pass us valid data
            return 'NODATA';
        }
	}
		
/**
 * This function is designed to grab all of the options from the DB but only display
 * those options which are not already in use by the item.
 * 
 * @param	itemid	=	Item ID of the item we are retrieving options for
 **/
	public function getAllItemOptions($itemid){
        $result = $this->db->sel($this->config['fpx'], 'items_options', 'options_id', 'item_id=' . $itemid);

        // Get Chosen Options from DB
        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $chosen[$i]=$row['options_id'];
        }

        $result = $this->db->sel($this->config['fpx'], 'options', 'id, name');
        // Get All Options in DB
        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $all[$i]['id'] = $row['id'];
            $all[$i]['name'] = $row['name'];
        }
		
        // Only display those options which are not chosen
        for ($k=0; $k < $i; $k++){
            $alreadyused='false';
            for($l=0; $l < sizeof($chosen); $l++){
                if ($all[$k]['id']==$chosen[$l]){
                    $alreadyused='true';
                }
            }
            if ($alreadyused=='false'){
                echo '<div id="alloptdiv_' . $all[$k]['id'] .  '" style="color: white; background-color: #1A496D; padding:5px; border-style: solid; border-width: 2px; border-color: #518BFF; margin: 3px; margin-left: 10px; margin-right: 10px;" class="alloptdivs">' . $all[$k]['name'] . '</div>';
            }
        }		
	}

/**
 * This is designed to grab the options already associated with the item
 * 
 * @param	itemid	=	The ID of the item we are retrieving options for
 **/
	public function getAllChosenOptions($itemid){
        $result = $this->db->sel($this->config['fpx'], 'items_options', 'options_id', 'item_id=' . $itemid . ' ORDER BY id');

        for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            $res = $this->db->sel($this->config['fpx'], 'options', 'id, name', 'id=' . $row['options_id']);
            $row = $res[0];
		
            echo '<div id="alloptdiv_' . $row['id'] . '" style="color: white; background-color: #1A496D; padding:5px; border-style: solid; border-width: 2px; border-color: #518BFF; margin: 3px; margin-left: 10px; margin-right: 10px;" class="alloptdivs">' . $row['name'] . '</div>';
        }
	}

/**
 * This is designed to grab all of the content templates from ModX
 * 
 * @param	tmplid		=	This is the id of the template being used
 * 
 * @return	An HTML dropdown of the templates in the system in the Content Templates
 * 			subcategory.
 **/
	public function getTemplates($tmplid){
		$result = $this->db->sel($this->config['pfx'], 'site_templates', 'templatename, id');
		
		echo '<select tabindex="10" id="templateid" name="templateid" >';
		
		for ($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
            if ($tmplid==$row['id']){
                $enbl='SELECTED';
            }else {
                $enbl='';
            }
            echo '<option ' . $enbl . ' name="' . $row['templatename'] . '" value="' . $row['id'] . '">' . $row['templatename'] . '</option>';
        }		
        echo '</select>';
	}
		
/**
 * This function is designed to return all chunks from ModX to use for
 * content area templates.
 * 
 * @param	catid	=	The category id, defaults to -1 which means
 * 						don't use the parameter if nothing is passed
 * 						in by the user;
 * 
 * @return	The code to display the chunks as a drop down menu
 **/
	public function getChunks($catid=-1){
		if ($catid==-1){
	        $result = $this->db->sel($this->config['pfx'], 'site_htmlsnippets', 'name, id');
		} else {
            $result = $this->db->sel($this->config['pfx'], 'site_htmlsnippets', 'name, id', 'category=' . $catid);	
		}
		
        echo '<select onchange="updatecontenttemplate();" tabindex="11" id="chunkid" name="chunkid">';
        echo '<option name="Default" value="NONE">Choose Content Template:</option>';
        for($i=0; $i < sizeof($result); $i++){
			$row = $result[$i];
			echo '<option name="chunkid-' . $row['id'] . '" value="' . $row['id'] . '">' . $row['name'] . '</option>';
//            echo '<option name="chunkid-' . $row['id'] . '" value="' . $row['id'] . '/>' . $row['name'] . '</option>';
        }
        echo '</select>';
	}		
		
/**
 * This function is designed to return the value of a chunk (HTML Code)
 * 
 * This is mainly used for the Administrative Interface to choose the content
 * template to use for a product page.
 * 
 * @param	chunkid	=	ID of the chunk to pull from the database.
 * 
 * @return	The content from the chunk with the given id
 **/
	public function getChunkContent($chunkid){
        $result = $this->db->sel($this->config['pfx'], 'site_htmlsnippets', 'snippet', 'id="' . $chunkid . '"');
        $row = $result[0];
        echo $row['snippet'];
	}
		
/**
 * This function is designed to return an array of customer information based on their webInternalKey
 * 
 * @param	webinternalkey	=	Customer's ModX webInternalKey
 * 
 * @return	An array of Customer information
 **/
	public function getCustomerInfo($webinternalkey){
		$result = $this->db->sel($this->config['fpx'], 'customers', 'fname, lname, addr1, addr2, city, state, zip, phone_1, phone_2, ext_1, ext_2, fax, companyname, country', 'custid=' . $webinternalkey);
		$row = $result[0];
		
        $ret['fname'] = $row['fname'];
        $ret['lname'] = $row['lname'];
        $ret['addr1'] = $row['addr1'];
        $ret['addr2'] = $row['addr2'];
        $ret['city'] = $row['city'];
        $ret['state'] = $row['state'];
        $ret['zip'] = $row['zip'];
        $ret['phone_1'] = $row['phone_1'];
        $ret['phone_2'] = $row['phone_2'];
        $ret['ext_1'] = $row['ext_1'];
        $ret['ext_2'] = $row['ext_2'];
        $ret['fax'] = $row['fax'];
        $ret['companyname'] = $row['companyname'];
        $ret['country'] = $row['country'];

        return $ret;		
	}
		
/**
 * This function is designed to create an order header with the details that the user provides.
 * 
 * It updates the fields found in the cart header for billing and shipping information
 * 
 * @param	TOO Many to List:	It takes in the session id and all POST data for billing and 
 *								shipping information
 **/
	public function updateCartForCheckout($sessionid, $emailbilling, $fnamebilling, $lnamebilling, $addr1billing, $addr2billing, $citybilling, $statebilling, $zipbilling, $phonebilling, $extbilling, $faxbilling, $companybilling, $companyship, $fnameship, $lnameship, $addr1ship, $addr2ship, $cityship, $stateship, $zipship, $phoneship, $extship){
        $this->db->upd($this->config['fpx'], 'cart_header', 'fname="' . $fnamebilling . '", lname="' . $lnamebilling . '", addr1="' . $addr1billing . '", addr2="' . $addr2billing . '", city="' . $citybilling . '", state="' . $statebilling . '", zip="' . $zipbilling . '", phone_1="' . $phonebilling . '", ext_1="' . $extbilling . '", fax="' . $faxbilling . '", company="' . $companybilling . '", shipcompany="' . $companyship . '", shipfname="' . $fnameship . '", shiplname="' . $lnameship . '", shipaddr1="' . $addr1ship . '", shipaddr2="' . $addr2ship . '", shipcity="' . $cityship . '", shipstate="' . $stateship . '", shipzip="' . $zipship . '", shipphone="' . $phoneship . '",  shipext="' . $extship . '"', 'session_id="' . $sessionid . '"');
	
//Updated by Bright @ 20080722	
//The code bellow is used for update the user information in the "customers" table, so the customers information will automatic update once customer place an new order.
//This is only used if the force customer login is enabled.
	if ($this->config['cart_forcelogin'] == 'ENABLED'){
        // $cust['internalKey'] is the internalKey of the modx user with the sessionid that was passed in, it should be linked to the customer's orders so
        // that their orders will properly show up in the customer account viewer.
        $result = $this->db->sel($this->config['pfx'], 'web_user_attributes', 'internalKey', 'sessionid="' . $sessionid . '"');
        $cust=$result[0];
		// Headerline information
		if ($cust['internalKey'] == ''){
			$c = 0;	
		} else {
			$c = $cust['internalKey'];	
		}
        $this->db->upd($this->config['fpx'], 'customers', 'fname="' . $fnamebilling . '", lname="' . $lnamebilling . '", addr1="' . $addr1billing . '", addr2="' . $addr2billing . '", city="' . $citybilling . '", state="' . $statebilling . '", zip="' . $zipbilling . '", phone_1="' . $phonebilling . '", ext_1="' . $extbilling . '", fax="' . $faxbilling . '", companyname="' . $companybilling . '"', 'custid="' . $c . '"');
	
	
		}

	
	}
	
	
	
//Updated by Bright @ 20080724	
//The following code is used for get the customer's currency selection. and will pass these value to getprice getship getsubtotal gethandle and gettotal
//so customer will see the final price in their currency.

	
		
/**
 * This function is designed to get the rate of customer's currency
 **/
/**
    public function getCurRate($curiso){

		$curid = $this->db->sel($this->config['fpx'], 'session_currency', 'currency_id', 'session_id="' . $sessionid . '"');
				
		//if customer did not select any curreny, currency will be default to USD
		if (!(sizeof($curid) > 0)){
			$curid = 46;
		} 
		$currate = $this->db->sel($this->config['fpx'], 'currency', 'currate', 'id='.$curid);

        return $currate;
		
    }
**/
	
	

//This function is designed to get the rate of customer's currency by curiso
    public function getCurRate($iso){
		$rs = $this->db->sel($this->config['fpx'], 'currency', 'currate', 'curiso="'.$iso.'"');
		$r = $rs[0];
		$rate = $r['currate'];
				
        return $rate;
		
    }

    public function getCurSym($iso){
		$rs = $this->db->sel($this->config['fpx'], 'currency', 'cursymbol', 'curiso="'.$iso.'"');
		$r = $rs[0];
		$sym = $r['cursymbol'];
				
        return $sym;
		
    }

	
	
	
	
    public function upDateCurrency(){
	
	  
	$doc = new DOMDocument();
	$doc->load('assets/snippets/shoppingCart/USD.xml');
	  
	$items = $doc->getElementsByTagName( "item" );
	foreach( $items as $item )  {

	$descriptions = $item->getElementsByTagName( "description" );
	$description = $descriptions->item(0)->nodeValue;
  
	$ratestart = strpos($description," = ") + 3;
	$ratefinish = strpos($description," ",$ratestart);
	$namefinish = strpos($description,"(",$ratefinish);
  
	$rate = substr($description,$ratestart,$ratefinish - $ratestart);
	$compos = strpos($rate,",");
  
	if ($compos != ""){$rate = substr_replace($rate,"",$compos,1);}
  
	$name = substr($description,$ratefinish + 1, $namefinish - $ratefinish - 2);
	$iso = substr($description,$namefinish + 1,3);

	//$result = mysql_query("SELECT * FROM kiwee_currency WHERE curiso='$iso'");
	$result = $this->db->sel($this->config['fpx'], 'currency', 'id, curiso, curname, cursymbol, currate', 'curiso="' . $iso . '"');
  
	//check if this currency is already exist	
	if (sizeof($result) > 0){
		$check = true;
	} else {
		$check = false;
	}
	
	//if not exist insert a new line
    if (!$check){
 		//mysql_query("INSERT INTO kiwee_currency (curiso, curname, currate) VALUES ('$iso', '$name', '$rate')");
		$this->db->ins($this->config['fpx'], 'currency',  'curiso, curname, currate', '"' . $iso . '","' . $name . '"'. $rate);
		
	//otherwise update the exist rate	  
    } else {
		//mysql_query("UPDATE kiwee_currency SET currate = '$rate'WHERE curiso = '$iso'");
		$this->db->upd($this->config['fpx'], 'currency', 'currate=' . $rate,'curiso="' . $iso . '"');
	}


   }

   }

  
	

	/**
    public function getCurISO($sessionid){
	
		$rs = $this->db->sel($this->config['fpx'], 'session_currency', 'currency_id', 'session_id="' . $sessionid . '"');
		
		//if customer did not select any curreny, currency will be default to AUD
		if (sizeof($rs) > 0){
			$r = $rs[0];
			$curid = $r['currency_id'];

		} else {
			$curid = 3;
		}
		
		$rs = $this->db->sel($this->config['fpx'], 'currency', 'curiso', 'id='.$curid);
		$r = $rs[0];
		$iso = $r['curiso'];
		
        return $iso;
		
    }
**/
	
	
	
}																																								
